1use crate::common_state::{CommonState, Context, IoState, State};
2use crate::enums::{AlertDescription, ContentType};
3use crate::error::{Error, PeerMisbehaved};
4#[cfg(feature = "logging")]
5use crate::log::trace;
6use crate::msgs::deframer::{Deframed, DeframerSliceBuffer, DeframerVecBuffer, MessageDeframer};
7use crate::msgs::handshake::Random;
8use crate::msgs::message::{Message, MessagePayload, PlainMessage};
9use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
10use crate::vecbuf::ChunkVecBuffer;
11
12use alloc::boxed::Box;
13use core::fmt::Debug;
14use core::mem;
15use core::ops::{Deref, DerefMut};
16use std::io;
17
18/// A client or server connection.
19#[derive(Debug)]
20pub enum Connection {
21 /// A client connection
22 Client(crate::client::ClientConnection),
23 /// A server connection
24 Server(crate::server::ServerConnection),
25}
26
27impl Connection {
28 /// Read TLS content from `rd`.
29 ///
30 /// See [`ConnectionCommon::read_tls()`] for more information.
31 pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
32 match self {
33 Self::Client(conn) => conn.read_tls(rd),
34 Self::Server(conn) => conn.read_tls(rd),
35 }
36 }
37
38 /// Writes TLS messages to `wr`.
39 ///
40 /// See [`ConnectionCommon::write_tls()`] for more information.
41 pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
42 self.sendable_tls.write_to(wr)
43 }
44
45 /// Returns an object that allows reading plaintext.
46 pub fn reader(&mut self) -> Reader {
47 match self {
48 Self::Client(conn) => conn.reader(),
49 Self::Server(conn) => conn.reader(),
50 }
51 }
52
53 /// Returns an object that allows writing plaintext.
54 pub fn writer(&mut self) -> Writer {
55 match self {
56 Self::Client(conn) => Writer::new(&mut **conn),
57 Self::Server(conn) => Writer::new(&mut **conn),
58 }
59 }
60
61 /// Processes any new packets read by a previous call to [`Connection::read_tls`].
62 ///
63 /// See [`ConnectionCommon::process_new_packets()`] for more information.
64 pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
65 match self {
66 Self::Client(conn) => conn.process_new_packets(),
67 Self::Server(conn) => conn.process_new_packets(),
68 }
69 }
70
71 /// Derives key material from the agreed connection secrets.
72 ///
73 /// See [`ConnectionCommon::export_keying_material()`] for more information.
74 pub fn export_keying_material<T: AsMut<[u8]>>(
75 &self,
76 output: T,
77 label: &[u8],
78 context: Option<&[u8]>,
79 ) -> Result<T, Error> {
80 match self {
81 Self::Client(conn) => conn.export_keying_material(output, label, context),
82 Self::Server(conn) => conn.export_keying_material(output, label, context),
83 }
84 }
85
86 /// This function uses `io` to complete any outstanding IO for this connection.
87 ///
88 /// See [`ConnectionCommon::complete_io()`] for more information.
89 pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
90 where
91 Self: Sized,
92 T: io::Read + io::Write,
93 {
94 match self {
95 Self::Client(conn) => conn.complete_io(io),
96 Self::Server(conn) => conn.complete_io(io),
97 }
98 }
99
100 /// Extract secrets, so they can be used when configuring kTLS, for example.
101 /// Should be used with care as it exposes secret key material.
102 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
103 match self {
104 Self::Client(client) => client.dangerous_extract_secrets(),
105 Self::Server(server) => server.dangerous_extract_secrets(),
106 }
107 }
108}
109
110impl Deref for Connection {
111 type Target = CommonState;
112
113 fn deref(&self) -> &Self::Target {
114 match self {
115 Self::Client(conn: &ClientConnection) => &conn.core.common_state,
116 Self::Server(conn: &ServerConnection) => &conn.core.common_state,
117 }
118 }
119}
120
121impl DerefMut for Connection {
122 fn deref_mut(&mut self) -> &mut Self::Target {
123 match self {
124 Self::Client(conn: &mut ClientConnection) => &mut conn.core.common_state,
125 Self::Server(conn: &mut ServerConnection) => &mut conn.core.common_state,
126 }
127 }
128}
129
130/// A structure that implements [`std::io::Read`] for reading plaintext.
131pub struct Reader<'a> {
132 received_plaintext: &'a mut ChunkVecBuffer,
133 peer_cleanly_closed: bool,
134 has_seen_eof: bool,
135}
136
137impl<'a> io::Read for Reader<'a> {
138 /// Obtain plaintext data received from the peer over this TLS connection.
139 ///
140 /// If the peer closes the TLS session cleanly, this returns `Ok(0)` once all
141 /// the pending data has been read. No further data can be received on that
142 /// connection, so the underlying TCP connection should be half-closed too.
143 ///
144 /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
145 /// `close_notify` alert) this function returns a `std::io::Error` of type
146 /// `ErrorKind::UnexpectedEof` once any pending data has been read.
147 ///
148 /// Note that support for `close_notify` varies in peer TLS libraries: many do not
149 /// support it and uncleanly close the TCP connection (this might be
150 /// vulnerable to truncation attacks depending on the application protocol).
151 /// This means applications using rustls must both handle EOF
152 /// from this function, *and* unexpected EOF of the underlying TCP connection.
153 ///
154 /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
155 ///
156 /// You may learn the number of bytes available at any time by inspecting
157 /// the return of [`Connection::process_new_packets`].
158 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
159 let len = self.received_plaintext.read(buf)?;
160
161 if len == 0 && !buf.is_empty() {
162 // No bytes available:
163 match (self.peer_cleanly_closed, self.has_seen_eof) {
164 // cleanly closed; don't care about TCP EOF: express this as Ok(0)
165 (true, _) => {}
166 // unclean closure
167 (false, true) => {
168 return Err(io::Error::new(
169 io::ErrorKind::UnexpectedEof,
170 UNEXPECTED_EOF_MESSAGE,
171 ))
172 }
173 // connection still going, but needs more data: signal `WouldBlock` so that
174 // the caller knows this
175 (false, false) => return Err(io::ErrorKind::WouldBlock.into()),
176 }
177 }
178
179 Ok(len)
180 }
181
182 /// Obtain plaintext data received from the peer over this TLS connection.
183 ///
184 /// If the peer closes the TLS session, this returns `Ok(())` without filling
185 /// any more of the buffer once all the pending data has been read. No further
186 /// data can be received on that connection, so the underlying TCP connection
187 /// should be half-closed too.
188 ///
189 /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
190 /// `close_notify` alert) this function returns a `std::io::Error` of type
191 /// `ErrorKind::UnexpectedEof` once any pending data has been read.
192 ///
193 /// Note that support for `close_notify` varies in peer TLS libraries: many do not
194 /// support it and uncleanly close the TCP connection (this might be
195 /// vulnerable to truncation attacks depending on the application protocol).
196 /// This means applications using rustls must both handle EOF
197 /// from this function, *and* unexpected EOF of the underlying TCP connection.
198 ///
199 /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
200 ///
201 /// You may learn the number of bytes available at any time by inspecting
202 /// the return of [`Connection::process_new_packets`].
203 #[cfg(read_buf)]
204 fn read_buf(&mut self, mut cursor: core::io::BorrowedCursor<'_>) -> io::Result<()> {
205 let before = cursor.written();
206 self.received_plaintext
207 .read_buf(cursor.reborrow())?;
208 let len = cursor.written() - before;
209
210 if len == 0 && cursor.capacity() > 0 {
211 // No bytes available:
212 match (self.peer_cleanly_closed, self.has_seen_eof) {
213 // cleanly closed; don't care about TCP EOF: express this as Ok(0)
214 (true, _) => {}
215 // unclean closure
216 (false, true) => {
217 return Err(io::Error::new(
218 io::ErrorKind::UnexpectedEof,
219 UNEXPECTED_EOF_MESSAGE,
220 ));
221 }
222 // connection still going, but need more data: signal `WouldBlock` so that
223 // the caller knows this
224 (false, false) => return Err(io::ErrorKind::WouldBlock.into()),
225 }
226 }
227
228 Ok(())
229 }
230}
231
232/// Internal trait implemented by the [`ServerConnection`]/[`ClientConnection`]
233/// allowing them to be the subject of a [`Writer`].
234///
235/// [`ServerConnection`]: crate::ServerConnection
236/// [`ClientConnection`]: crate::ClientConnection
237pub(crate) trait PlaintextSink {
238 fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
239 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize>;
240 fn flush(&mut self) -> io::Result<()>;
241}
242
243impl<T> PlaintextSink for ConnectionCommon<T> {
244 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
245 Ok(self.send_some_plaintext(data:buf))
246 }
247
248 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
249 let mut sz: usize = 0;
250 for buf: &IoSlice<'_> in bufs {
251 sz += self.send_some_plaintext(data:buf);
252 }
253 Ok(sz)
254 }
255
256 fn flush(&mut self) -> io::Result<()> {
257 Ok(())
258 }
259}
260
261/// A structure that implements [`std::io::Write`] for writing plaintext.
262pub struct Writer<'a> {
263 sink: &'a mut dyn PlaintextSink,
264}
265
266impl<'a> Writer<'a> {
267 /// Create a new Writer.
268 ///
269 /// This is not an external interface. Get one of these objects
270 /// from [`Connection::writer`].
271 pub(crate) fn new(sink: &'a mut dyn PlaintextSink) -> Writer<'a> {
272 Writer { sink }
273 }
274}
275
276impl<'a> io::Write for Writer<'a> {
277 /// Send the plaintext `buf` to the peer, encrypting
278 /// and authenticating it. Once this function succeeds
279 /// you should call [`Connection::write_tls`] which will output the
280 /// corresponding TLS records.
281 ///
282 /// This function buffers plaintext sent before the
283 /// TLS handshake completes, and sends it as soon
284 /// as it can. See [`CommonState::set_buffer_limit`] to control
285 /// the size of this buffer.
286 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
287 self.sink.write(buf)
288 }
289
290 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
291 self.sink.write_vectored(bufs)
292 }
293
294 fn flush(&mut self) -> io::Result<()> {
295 self.sink.flush()
296 }
297}
298
299#[derive(Debug)]
300pub(crate) struct ConnectionRandoms {
301 pub(crate) client: [u8; 32],
302 pub(crate) server: [u8; 32],
303}
304
305/// How many ChangeCipherSpec messages we accept and drop in TLS1.3 handshakes.
306/// The spec says 1, but implementations (namely the boringssl test suite) get
307/// this wrong. BoringSSL itself accepts up to 32.
308static TLS13_MAX_DROPPED_CCS: u8 = 2u8;
309
310impl ConnectionRandoms {
311 pub(crate) fn new(client: Random, server: Random) -> Self {
312 Self {
313 client: client.0,
314 server: server.0,
315 }
316 }
317}
318
319// --- Common (to client and server) connection functions ---
320
321fn is_valid_ccs(msg: &PlainMessage) -> bool {
322 // We passthrough ChangeCipherSpec messages in the deframer without decrypting them.
323 // Note: this is prior to the record layer, so is unencrypted. See
324 // third paragraph of section 5 in RFC8446.
325 msg.typ == ContentType::ChangeCipherSpec && msg.payload.0 == [0x01]
326}
327
328/// Interface shared by client and server connections.
329pub struct ConnectionCommon<Data> {
330 pub(crate) core: ConnectionCore<Data>,
331 deframer_buffer: DeframerVecBuffer,
332}
333
334impl<Data> ConnectionCommon<Data> {
335 /// Returns an object that allows reading plaintext.
336 pub fn reader(&mut self) -> Reader {
337 let common = &mut self.core.common_state;
338 Reader {
339 received_plaintext: &mut common.received_plaintext,
340 // Are we done? i.e., have we processed all received messages, and received a
341 // close_notify to indicate that no new messages will arrive?
342 peer_cleanly_closed: common.has_received_close_notify
343 && !self.deframer_buffer.has_pending(),
344 has_seen_eof: common.has_seen_eof,
345 }
346 }
347
348 /// Returns an object that allows writing plaintext.
349 pub fn writer(&mut self) -> Writer {
350 Writer::new(self)
351 }
352
353 /// This function uses `io` to complete any outstanding IO for
354 /// this connection.
355 ///
356 /// This is a convenience function which solely uses other parts
357 /// of the public API.
358 ///
359 /// What this means depends on the connection state:
360 ///
361 /// - If the connection [`is_handshaking`], then IO is performed until
362 /// the handshake is complete.
363 /// - Otherwise, if [`wants_write`] is true, [`write_tls`] is invoked
364 /// until it is all written.
365 /// - Otherwise, if [`wants_read`] is true, [`read_tls`] is invoked
366 /// once.
367 ///
368 /// The return value is the number of bytes read from and written
369 /// to `io`, respectively.
370 ///
371 /// This function will block if `io` blocks.
372 ///
373 /// Errors from TLS record handling (i.e., from [`process_new_packets`])
374 /// are wrapped in an `io::ErrorKind::InvalidData`-kind error.
375 ///
376 /// [`is_handshaking`]: CommonState::is_handshaking
377 /// [`wants_read`]: CommonState::wants_read
378 /// [`wants_write`]: CommonState::wants_write
379 /// [`write_tls`]: ConnectionCommon::write_tls
380 /// [`read_tls`]: ConnectionCommon::read_tls
381 /// [`process_new_packets`]: ConnectionCommon::process_new_packets
382 pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
383 where
384 Self: Sized,
385 T: io::Read + io::Write,
386 {
387 let mut eof = false;
388 let mut wrlen = 0;
389 let mut rdlen = 0;
390
391 loop {
392 let until_handshaked = self.is_handshaking();
393
394 while self.wants_write() {
395 wrlen += self.write_tls(io)?;
396 }
397 io.flush()?;
398
399 if !until_handshaked && wrlen > 0 {
400 return Ok((rdlen, wrlen));
401 }
402
403 while !eof && self.wants_read() {
404 let read_size = match self.read_tls(io) {
405 Ok(0) => {
406 eof = true;
407 Some(0)
408 }
409 Ok(n) => {
410 rdlen += n;
411 Some(n)
412 }
413 Err(ref err) if err.kind() == io::ErrorKind::Interrupted => None, // nothing to do
414 Err(err) => return Err(err),
415 };
416 if read_size.is_some() {
417 break;
418 }
419 }
420
421 match self.process_new_packets() {
422 Ok(_) => {}
423 Err(e) => {
424 // In case we have an alert to send describing this error,
425 // try a last-gasp write -- but don't predate the primary
426 // error.
427 let _ignored = self.write_tls(io);
428 let _ignored = io.flush();
429
430 return Err(io::Error::new(io::ErrorKind::InvalidData, e));
431 }
432 };
433
434 // if we're doing IO until handshaked, and we believe we've finished handshaking,
435 // but process_new_packets() has queued TLS data to send, loop around again to write
436 // the queued messages.
437 if until_handshaked && !self.is_handshaking() && self.wants_write() {
438 continue;
439 }
440
441 match (eof, until_handshaked, self.is_handshaking()) {
442 (_, true, false) => return Ok((rdlen, wrlen)),
443 (_, false, _) => return Ok((rdlen, wrlen)),
444 (true, true, true) => return Err(io::Error::from(io::ErrorKind::UnexpectedEof)),
445 (..) => {}
446 }
447 }
448 }
449
450 /// Extract the first handshake message.
451 ///
452 /// This is a shortcut to the `process_new_packets()` -> `process_msg()` ->
453 /// `process_handshake_messages()` path, specialized for the first handshake message.
454 pub(crate) fn first_handshake_message(&mut self) -> Result<Option<Message>, Error> {
455 let mut deframer_buffer = self.deframer_buffer.borrow();
456 let res = self
457 .core
458 .deframe(None, &mut deframer_buffer);
459 let discard = deframer_buffer.pending_discard();
460 self.deframer_buffer.discard(discard);
461
462 match res?.map(Message::try_from) {
463 Some(Ok(msg)) => Ok(Some(msg)),
464 Some(Err(err)) => Err(self.send_fatal_alert(AlertDescription::DecodeError, err)),
465 None => Ok(None),
466 }
467 }
468
469 pub(crate) fn replace_state(&mut self, new: Box<dyn State<Data>>) {
470 self.core.state = Ok(new);
471 }
472
473 /// Processes any new packets read by a previous call to
474 /// [`Connection::read_tls`].
475 ///
476 /// Errors from this function relate to TLS protocol errors, and
477 /// are fatal to the connection. Future calls after an error will do
478 /// no new work and will return the same error. After an error is
479 /// received from [`process_new_packets`], you should not call [`read_tls`]
480 /// any more (it will fill up buffers to no purpose). However, you
481 /// may call the other methods on the connection, including `write`,
482 /// `send_close_notify`, and `write_tls`. Most likely you will want to
483 /// call `write_tls` to send any alerts queued by the error and then
484 /// close the underlying connection.
485 ///
486 /// Success from this function comes with some sundry state data
487 /// about the connection.
488 ///
489 /// [`read_tls`]: Connection::read_tls
490 /// [`process_new_packets`]: Connection::process_new_packets
491 #[inline]
492 pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
493 self.core
494 .process_new_packets(&mut self.deframer_buffer)
495 }
496
497 /// Read TLS content from `rd` into the internal buffer.
498 ///
499 /// Due to the internal buffering, `rd` can supply TLS messages in arbitrary-sized chunks (like
500 /// a socket or pipe might).
501 ///
502 /// You should call [`process_new_packets()`] each time a call to this function succeeds in order
503 /// to empty the incoming TLS data buffer.
504 ///
505 /// This function returns `Ok(0)` when the underlying `rd` does so. This typically happens when
506 /// a socket is cleanly closed, or a file is at EOF. Errors may result from the IO done through
507 /// `rd`; additionally, errors of `ErrorKind::Other` are emitted to signal backpressure:
508 ///
509 /// * In order to empty the incoming TLS data buffer, you should call [`process_new_packets()`]
510 /// each time a call to this function succeeds.
511 /// * In order to empty the incoming plaintext data buffer, you should empty it through
512 /// the [`reader()`] after the call to [`process_new_packets()`].
513 ///
514 /// [`process_new_packets()`]: ConnectionCommon::process_new_packets
515 /// [`reader()`]: ConnectionCommon::reader
516 pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
517 if self.received_plaintext.is_full() {
518 return Err(io::Error::new(
519 io::ErrorKind::Other,
520 "received plaintext buffer full",
521 ));
522 }
523
524 let res = self
525 .core
526 .message_deframer
527 .read(rd, &mut self.deframer_buffer);
528 if let Ok(0) = res {
529 self.has_seen_eof = true;
530 }
531 res
532 }
533
534 /// Writes TLS messages to `wr`.
535 ///
536 /// On success, this function returns `Ok(n)` where `n` is a number of bytes written to `wr`
537 /// (after encoding and encryption).
538 ///
539 /// After this function returns, the connection buffer may not yet be fully flushed. The
540 /// [`CommonState::wants_write`] function can be used to check if the output buffer is empty.
541 pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
542 self.sendable_tls.write_to(wr)
543 }
544
545 /// Derives key material from the agreed connection secrets.
546 ///
547 /// This function fills in `output` with `output.len()` bytes of key
548 /// material derived from the master session secret using `label`
549 /// and `context` for diversification. Ownership of the buffer is taken
550 /// by the function and returned via the Ok result to ensure no key
551 /// material leaks if the function fails.
552 ///
553 /// See RFC5705 for more details on what this does and is for.
554 ///
555 /// For TLS1.3 connections, this function does not use the
556 /// "early" exporter at any point.
557 ///
558 /// This function fails if called prior to the handshake completing;
559 /// check with [`CommonState::is_handshaking`] first.
560 ///
561 /// This function fails if `output.len()` is zero.
562 #[inline]
563 pub fn export_keying_material<T: AsMut<[u8]>>(
564 &self,
565 output: T,
566 label: &[u8],
567 context: Option<&[u8]>,
568 ) -> Result<T, Error> {
569 self.core
570 .export_keying_material(output, label, context)
571 }
572
573 /// Extract secrets, so they can be used when configuring kTLS, for example.
574 /// Should be used with care as it exposes secret key material.
575 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
576 if !self.enable_secret_extraction {
577 return Err(Error::General("Secret extraction is disabled".into()));
578 }
579
580 let st = self.core.state?;
581
582 let record_layer = self.core.common_state.record_layer;
583 let PartiallyExtractedSecrets { tx, rx } = st.extract_secrets()?;
584 Ok(ExtractedSecrets {
585 tx: (record_layer.write_seq(), tx),
586 rx: (record_layer.read_seq(), rx),
587 })
588 }
589}
590
591impl<'a, Data> From<&'a mut ConnectionCommon<Data>> for Context<'a, Data> {
592 fn from(conn: &'a mut ConnectionCommon<Data>) -> Self {
593 Self {
594 common: &mut conn.core.common_state,
595 data: &mut conn.core.data,
596 }
597 }
598}
599
600impl<T> Deref for ConnectionCommon<T> {
601 type Target = CommonState;
602
603 fn deref(&self) -> &Self::Target {
604 &self.core.common_state
605 }
606}
607
608impl<T> DerefMut for ConnectionCommon<T> {
609 fn deref_mut(&mut self) -> &mut Self::Target {
610 &mut self.core.common_state
611 }
612}
613
614impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
615 fn from(core: ConnectionCore<Data>) -> Self {
616 Self {
617 core,
618 deframer_buffer: DeframerVecBuffer::default(),
619 }
620 }
621}
622
623pub(crate) struct ConnectionCore<Data> {
624 pub(crate) state: Result<Box<dyn State<Data>>, Error>,
625 pub(crate) data: Data,
626 pub(crate) common_state: CommonState,
627 pub(crate) message_deframer: MessageDeframer,
628}
629
630impl<Data> ConnectionCore<Data> {
631 pub(crate) fn new(state: Box<dyn State<Data>>, data: Data, common_state: CommonState) -> Self {
632 Self {
633 state: Ok(state),
634 data,
635 common_state,
636 message_deframer: MessageDeframer::default(),
637 }
638 }
639
640 pub(crate) fn process_new_packets(
641 &mut self,
642 deframer_buffer: &mut DeframerVecBuffer,
643 ) -> Result<IoState, Error> {
644 let mut state = match mem::replace(&mut self.state, Err(Error::HandshakeNotComplete)) {
645 Ok(state) => state,
646 Err(e) => {
647 self.state = Err(e.clone());
648 return Err(e);
649 }
650 };
651
652 let mut borrowed_buffer = deframer_buffer.borrow();
653 while let Some(msg) = self.deframe(Some(&*state), &mut borrowed_buffer)? {
654 match self.process_msg(msg, state) {
655 Ok(new) => state = new,
656 Err(e) => {
657 self.state = Err(e.clone());
658 let discard = borrowed_buffer.pending_discard();
659 deframer_buffer.discard(discard);
660 return Err(e);
661 }
662 }
663 }
664
665 let discard = borrowed_buffer.pending_discard();
666 deframer_buffer.discard(discard);
667 self.state = Ok(state);
668 Ok(self.common_state.current_io_state())
669 }
670
671 /// Pull a message out of the deframer and send any messages that need to be sent as a result.
672 fn deframe(
673 &mut self,
674 state: Option<&dyn State<Data>>,
675 deframer_buffer: &mut DeframerSliceBuffer,
676 ) -> Result<Option<PlainMessage>, Error> {
677 match self.message_deframer.pop(
678 &mut self.common_state.record_layer,
679 self.common_state.negotiated_version,
680 deframer_buffer,
681 ) {
682 Ok(Some(Deframed {
683 want_close_before_decrypt,
684 aligned,
685 trial_decryption_finished,
686 message,
687 })) => {
688 if want_close_before_decrypt {
689 self.common_state.send_close_notify();
690 }
691
692 if trial_decryption_finished {
693 self.common_state
694 .record_layer
695 .finish_trial_decryption();
696 }
697
698 self.common_state.aligned_handshake = aligned;
699 Ok(Some(message))
700 }
701 Ok(None) => Ok(None),
702 Err(err @ Error::InvalidMessage(_)) => {
703 if self.common_state.is_quic() {
704 self.common_state.quic.alert = Some(AlertDescription::DecodeError);
705 }
706
707 Err(if !self.common_state.is_quic() {
708 self.common_state
709 .send_fatal_alert(AlertDescription::DecodeError, err)
710 } else {
711 err
712 })
713 }
714 Err(err @ Error::PeerSentOversizedRecord) => Err(self
715 .common_state
716 .send_fatal_alert(AlertDescription::RecordOverflow, err)),
717 Err(err @ Error::DecryptError) => {
718 if let Some(state) = state {
719 state.handle_decrypt_error();
720 }
721 Err(self
722 .common_state
723 .send_fatal_alert(AlertDescription::BadRecordMac, err))
724 }
725 Err(e) => Err(e),
726 }
727 }
728
729 fn process_msg(
730 &mut self,
731 msg: PlainMessage,
732 state: Box<dyn State<Data>>,
733 ) -> Result<Box<dyn State<Data>>, Error> {
734 // Drop CCS messages during handshake in TLS1.3
735 if msg.typ == ContentType::ChangeCipherSpec
736 && !self
737 .common_state
738 .may_receive_application_data
739 && self.common_state.is_tls13()
740 {
741 if !is_valid_ccs(&msg)
742 || self.common_state.received_middlebox_ccs > TLS13_MAX_DROPPED_CCS
743 {
744 // "An implementation which receives any other change_cipher_spec value or
745 // which receives a protected change_cipher_spec record MUST abort the
746 // handshake with an "unexpected_message" alert."
747 return Err(self.common_state.send_fatal_alert(
748 AlertDescription::UnexpectedMessage,
749 PeerMisbehaved::IllegalMiddleboxChangeCipherSpec,
750 ));
751 } else {
752 self.common_state.received_middlebox_ccs += 1;
753 trace!("Dropping CCS");
754 return Ok(state);
755 }
756 }
757
758 // Now we can fully parse the message payload.
759 let msg = match Message::try_from(msg) {
760 Ok(msg) => msg,
761 Err(err) => {
762 return Err(self
763 .common_state
764 .send_fatal_alert(AlertDescription::DecodeError, err));
765 }
766 };
767
768 // For alerts, we have separate logic.
769 if let MessagePayload::Alert(alert) = &msg.payload {
770 self.common_state.process_alert(alert)?;
771 return Ok(state);
772 }
773
774 self.common_state
775 .process_main_protocol(msg, state, &mut self.data)
776 }
777
778 pub(crate) fn export_keying_material<T: AsMut<[u8]>>(
779 &self,
780 mut output: T,
781 label: &[u8],
782 context: Option<&[u8]>,
783 ) -> Result<T, Error> {
784 if output.as_mut().is_empty() {
785 return Err(Error::General(
786 "export_keying_material with zero-length output".into(),
787 ));
788 }
789
790 match self.state.as_ref() {
791 Ok(st) => st
792 .export_keying_material(output.as_mut(), label, context)
793 .map(|_| output),
794 Err(e) => Err(e.clone()),
795 }
796 }
797}
798
799/// Data specific to the peer's side (client or server).
800pub trait SideData: Debug {}
801
802const UNEXPECTED_EOF_MESSAGE: &str = "peer closed connection without sending TLS close_notify: \
803https://docs.rs/rustls/latest/rustls/manual/_03_howto/index.html#unexpected-eof";
804

Provided by KDAB

Privacy Policy
Learn Rust with the experts
Find out more