cometbft_p2p/
secret_connection.rs1use crate::{
4 Error, MAX_MSG_LEN, PublicKey, Result,
5 ed25519::{self, Signer},
6 encryption::{Frame, RecvState, SendState},
7 handshake, proto,
8 traits::{ReadMsg, TryCloneIo, WriteMsg},
9};
10use prost::Message;
11use std::io::{self, Read, Write};
12
13#[cfg(doc)]
14use crate::IdentitySecret;
15
16pub struct SecretConnection<Io> {
33 reader: SecretReader<Io>,
36
37 writer: SecretWriter<Io>,
40
41 local_public_key: PublicKey,
43
44 peer_public_key: PublicKey,
46}
47
48impl<Io: Read + Write + Send + Sync + TryCloneIo> SecretConnection<Io> {
49 pub fn new<Identity>(mut io: Io, identity_key: &Identity) -> Result<Self>
61 where
62 Identity: Signer<ed25519::Signature>,
63 ed25519::VerifyingKey: for<'a> From<&'a Identity>,
64 {
65 let local_public_key: PublicKey = ed25519::VerifyingKey::from(identity_key).into();
67 let (mut initial_state, initial_message) = handshake::InitialState::new();
68
69 io.write_msg(&initial_message)?;
71
72 let peer_initial_message: handshake::InitialMessage = io.read_msg()?;
74
75 let (challenge, cipher_state) = initial_state.got_key(peer_initial_message.pub_key)?;
78
79 let io2 = io.try_clone()?;
81 let mut reader = SecretReader {
82 io,
83 recv_state: cipher_state.recv_state,
84 };
85 let mut writer = SecretWriter {
86 io: io2,
87 send_state: cipher_state.send_state,
88 };
89
90 writer.write_msg(&proto::p2p::AuthSigMessage {
92 pub_key: Some(local_public_key.into()),
93 sig: challenge.sign_challenge(identity_key).to_vec(),
94 })?;
95
96 let auth_sig_msg: proto::p2p::AuthSigMessage = reader.read_msg()?;
99
100 let peer_public_key = challenge.got_signature(auth_sig_msg)?;
102
103 Ok(Self {
105 reader,
106 writer,
107 local_public_key,
108 peer_public_key,
109 })
110 }
111}
112
113impl<M: Message + Default, Io: Read> ReadMsg<M> for SecretConnection<Io> {
114 fn read_msg(&mut self) -> Result<M> {
115 self.reader.read_msg()
116 }
117}
118
119impl<M: Message, Io: Write> WriteMsg<M> for SecretConnection<Io> {
120 fn write_msg(&mut self, msg: &M) -> Result<()> {
121 self.writer.write_msg(msg)
122 }
123}
124
125impl<Io: Write> SecretConnection<Io> {
126 pub fn flush(&mut self) -> io::Result<()> {
128 self.writer.flush()
129 }
130}
131
132impl<Io> SecretConnection<Io> {
133 pub fn local_public_key(&self) -> &PublicKey {
135 &self.local_public_key
136 }
137
138 pub fn peer_public_key(&self) -> &PublicKey {
140 &self.peer_public_key
141 }
142
143 pub fn split(self) -> (SecretReader<Io>, SecretWriter<Io>) {
146 (self.reader, self.writer)
147 }
148}
149
150pub struct SecretReader<Io> {
152 io: Io,
154
155 recv_state: RecvState,
157}
158
159impl<Io: Read> SecretReader<Io> {
160 #[inline]
162 fn read_frame(&mut self) -> Result<Frame> {
163 let mut bytes = [0u8; Frame::ENCRYPTED_SIZE];
164 self.io.read_exact(&mut bytes)?;
165
166 let mut frame = Frame::from_ciphertext(bytes);
167 self.recv_state.decrypt_frame(&mut frame)?;
168 Ok(frame)
169 }
170}
171
172impl<M: Message + Default, Io: Read> ReadMsg<M> for SecretReader<Io> {
173 fn read_msg(&mut self) -> Result<M> {
174 let frame = self.read_frame()?;
175 let frame_plaintext = frame.plaintext()?;
176
177 let msg_len = proto::decode_length_delimiter_inclusive(frame_plaintext)?;
179
180 if msg_len > MAX_MSG_LEN {
181 return Err(Error::MessageSize { size: msg_len });
182 }
183
184 if frame_plaintext.len() == msg_len {
186 return Ok(M::decode_length_delimited(frame_plaintext)?);
187 }
188
189 let mut msg = Vec::with_capacity(msg_len);
190 msg.extend_from_slice(frame_plaintext);
191
192 while msg.len() < msg_len {
193 msg.extend_from_slice(self.read_frame()?.plaintext()?);
194 }
195
196 Ok(M::decode_length_delimited(msg.as_slice())?)
197 }
198}
199
200pub struct SecretWriter<Io> {
202 io: Io,
204
205 send_state: SendState,
207}
208
209impl<Io: Write> SecretWriter<Io> {
210 pub fn flush(&mut self) -> io::Result<()> {
212 self.io.flush()
213 }
214
215 #[inline]
217 fn write_frame(&mut self, plaintext: &[u8]) -> Result<()> {
218 let mut frame = Frame::from_plaintext(plaintext)?;
219 self.send_state.encrypt_frame(&mut frame)?;
220 Ok(self.io.write_all(frame.ciphertext()?)?)
221 }
222}
223
224impl<M: Message, Io: Write> WriteMsg<M> for SecretWriter<Io> {
225 fn write_msg(&mut self, msg: &M) -> Result<()> {
226 let bytes = msg.encode_length_delimited_to_vec();
227
228 for chunk in bytes.chunks(Frame::MAX_PLAINTEXT_SIZE) {
229 self.write_frame(chunk)?;
230 }
231
232 Ok(())
233 }
234}
235
236