rustls/
record_layer.rs
1use crate::cipher::{MessageDecrypter, MessageEncrypter};
2use crate::error::Error;
3use crate::msgs::message::{BorrowedPlainMessage, OpaqueMessage, PlainMessage};
4
5#[cfg(feature = "logging")]
6use crate::log::trace;
7
8static SEQ_SOFT_LIMIT: u64 = 0xffff_ffff_ffff_0000u64;
9static SEQ_HARD_LIMIT: u64 = 0xffff_ffff_ffff_fffeu64;
10
11#[derive(PartialEq)]
12enum DirectionState {
13 Invalid,
15
16 Prepared,
18
19 Active,
21}
22
23pub struct RecordLayer {
25 message_encrypter: Box<dyn MessageEncrypter>,
26 message_decrypter: Box<dyn MessageDecrypter>,
27 write_seq: u64,
28 read_seq: u64,
29 encrypt_state: DirectionState,
30 decrypt_state: DirectionState,
31
32 trial_decryption_len: Option<usize>,
36}
37
38impl RecordLayer {
39 pub fn new() -> Self {
41 Self {
42 message_encrypter: <dyn MessageEncrypter>::invalid(),
43 message_decrypter: <dyn MessageDecrypter>::invalid(),
44 write_seq: 0,
45 read_seq: 0,
46 encrypt_state: DirectionState::Invalid,
47 decrypt_state: DirectionState::Invalid,
48 trial_decryption_len: None,
49 }
50 }
51
52 pub(crate) fn is_encrypting(&self) -> bool {
53 self.encrypt_state == DirectionState::Active
54 }
55
56 #[cfg(feature = "secret_extraction")]
57 pub(crate) fn write_seq(&self) -> u64 {
58 self.write_seq
59 }
60
61 #[cfg(feature = "secret_extraction")]
62 pub(crate) fn read_seq(&self) -> u64 {
63 self.read_seq
64 }
65
66 fn doing_trial_decryption(&mut self, requested: usize) -> bool {
67 match self
68 .trial_decryption_len
69 .and_then(|value| value.checked_sub(requested))
70 {
71 Some(remaining) => {
72 self.trial_decryption_len = Some(remaining);
73 true
74 }
75 _ => false,
76 }
77 }
78
79 pub(crate) fn prepare_message_encrypter(&mut self, cipher: Box<dyn MessageEncrypter>) {
82 self.message_encrypter = cipher;
83 self.write_seq = 0;
84 self.encrypt_state = DirectionState::Prepared;
85 }
86
87 pub(crate) fn prepare_message_decrypter(&mut self, cipher: Box<dyn MessageDecrypter>) {
90 self.message_decrypter = cipher;
91 self.read_seq = 0;
92 self.decrypt_state = DirectionState::Prepared;
93 }
94
95 pub(crate) fn start_encrypting(&mut self) {
98 debug_assert!(self.encrypt_state == DirectionState::Prepared);
99 self.encrypt_state = DirectionState::Active;
100 }
101
102 pub(crate) fn start_decrypting(&mut self) {
105 debug_assert!(self.decrypt_state == DirectionState::Prepared);
106 self.decrypt_state = DirectionState::Active;
107 }
108
109 pub(crate) fn set_message_encrypter(&mut self, cipher: Box<dyn MessageEncrypter>) {
112 self.prepare_message_encrypter(cipher);
113 self.start_encrypting();
114 }
115
116 pub(crate) fn set_message_decrypter(&mut self, cipher: Box<dyn MessageDecrypter>) {
119 self.prepare_message_decrypter(cipher);
120 self.start_decrypting();
121 self.trial_decryption_len = None;
122 }
123
124 pub(crate) fn set_message_decrypter_with_trial_decryption(
128 &mut self,
129 cipher: Box<dyn MessageDecrypter>,
130 max_length: usize,
131 ) {
132 self.prepare_message_decrypter(cipher);
133 self.start_decrypting();
134 self.trial_decryption_len = Some(max_length);
135 }
136
137 pub(crate) fn finish_trial_decryption(&mut self) {
138 self.trial_decryption_len = None;
139 }
140
141 pub(crate) fn wants_close_before_encrypt(&self) -> bool {
144 self.write_seq == SEQ_SOFT_LIMIT
145 }
146
147 pub(crate) fn encrypt_exhausted(&self) -> bool {
150 self.write_seq >= SEQ_HARD_LIMIT
151 }
152
153 pub(crate) fn decrypt_incoming(
159 &mut self,
160 encr: OpaqueMessage,
161 ) -> Result<Option<Decrypted>, Error> {
162 if self.decrypt_state != DirectionState::Active {
163 return Ok(Some(Decrypted {
164 want_close_before_decrypt: false,
165 plaintext: encr.into_plain_message(),
166 }));
167 }
168
169 let want_close_before_decrypt = self.read_seq == SEQ_SOFT_LIMIT;
178
179 let encrypted_len = encr.payload.0.len();
180 match self
181 .message_decrypter
182 .decrypt(encr, self.read_seq)
183 {
184 Ok(plaintext) => {
185 self.read_seq += 1;
186 Ok(Some(Decrypted {
187 want_close_before_decrypt,
188 plaintext,
189 }))
190 }
191 Err(Error::DecryptError) if self.doing_trial_decryption(encrypted_len) => {
192 trace!("Dropping undecryptable message after aborted early_data");
193 Ok(None)
194 }
195 Err(err) => Err(err),
196 }
197 }
198
199 pub(crate) fn encrypt_outgoing(&mut self, plain: BorrowedPlainMessage) -> OpaqueMessage {
204 debug_assert!(self.encrypt_state == DirectionState::Active);
205 assert!(!self.encrypt_exhausted());
206 let seq = self.write_seq;
207 self.write_seq += 1;
208 self.message_encrypter
209 .encrypt(plain, seq)
210 .unwrap()
211 }
212}
213
214#[derive(Debug)]
216pub struct Decrypted {
217 pub want_close_before_decrypt: bool,
219 pub plaintext: PlainMessage,
221}