brass_aphid_wire_decryption/decryption/
mod.rs1use std::{ffi::c_void, io::ErrorKind};
2
3use crate::decryption::{
4 key_manager::KeyManager,
5 s2n_tls_intercept::{generic_recv_cb, generic_send_cb, ArchaicCPipe, PeerIntoS2ntlsInsides},
6 stream_decrypter::StreamDecrypter,
7};
8
9pub mod key_manager;
10pub mod key_space;
11pub mod s2n_tls_intercept;
12pub mod stream_decrypter;
13pub mod tls_stream;
14pub mod transcript;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum Mode {
18 Client,
19 Server,
20}
21
22impl Mode {
23 pub fn peer(&self) -> Mode {
24 match self {
25 Mode::Client => Mode::Server,
26 Mode::Server => Mode::Client,
27 }
28 }
29}
30
31pub struct DecryptingPipe<T> {
45 pub pipe: T,
46 pub decrypter: StreamDecrypter,
49 pub identity: Option<Mode>,
50}
51
52impl DecryptingPipe<ArchaicCPipe> {
53 pub fn s2n_tls_decrypter(
58 key_manager: KeyManager,
59 connection: &mut s2n_tls::connection::Connection,
60 ) -> Box<Self> {
61 let original_send = connection.steal_send_cb();
62 let original_recv = connection.steal_recv_cb();
63 let original_pipe = ArchaicCPipe::new(original_send, original_recv);
64 let decrypter = Self::new(key_manager, original_pipe);
65 let decrypter = Box::new(decrypter);
66
67 connection
68 .set_send_callback(Some(generic_send_cb::<Self>))
69 .unwrap();
70 connection
71 .set_receive_callback(Some(generic_recv_cb::<Self>))
72 .unwrap();
73 unsafe {
74 connection
75 .set_send_context(decrypter.as_ref() as *const Self as *mut c_void)
76 .unwrap();
77 connection
78 .set_receive_context(decrypter.as_ref() as *const Self as *mut c_void)
79 .unwrap();
80 }
81 decrypter
82 }
83}
84
85impl<T: std::io::Read + std::io::Write> DecryptingPipe<T> {
86 pub fn new(key_manager: KeyManager, pipe: T) -> Self {
87 Self {
88 pipe,
89 decrypter: StreamDecrypter::new(key_manager),
90 identity: None,
91 }
92 }
93
94 pub fn enable_s2n_tls_decryption(
100 decrypter: &Box<Self>,
101 connection: &mut s2n_tls::connection::Connection,
102 ) {
103 connection
104 .set_send_callback(Some(generic_send_cb::<Self>))
105 .unwrap();
106 connection
107 .set_receive_callback(Some(generic_recv_cb::<Self>))
108 .unwrap();
109 unsafe {
110 connection
111 .set_send_context(decrypter.as_ref() as *const Self as *mut c_void)
112 .unwrap();
113 connection
114 .set_receive_context(decrypter.as_ref() as *const Self as *mut c_void)
115 .unwrap();
116 }
117 }
118}
119
120impl<T: std::io::Read> std::io::Read for DecryptingPipe<T> {
123 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
124 if self.identity.is_none() {
125 self.identity = Some(Mode::Server);
127 }
128
129 let read = self.pipe.read(buf)?;
130 tracing::trace!("DecryptingPipe read {read} bytes");
131
132 let peer = self.identity.unwrap().peer();
133
134 self.decrypter.record_tx(&buf[..read], peer);
135 self.decrypter.assemble_records(peer);
136 if let Err(e) = self.decrypter.decrypt_records(peer) {
138 if e.kind() != ErrorKind::UnexpectedEof {
139 panic!("unexpected error: {e}");
140 }
141 }
142
143 Ok(read)
144 }
145}
146
147impl<T: std::io::Write> std::io::Write for DecryptingPipe<T> {
148 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
149 if self.identity.is_none() {
150 self.identity = Some(Mode::Client);
152 }
153
154 let written = self.pipe.write(buf)?;
155 tracing::trace!("DecryptingPipe wrote {written} bytes");
156
157 let identity = self.identity.unwrap();
158
159 self.decrypter.record_tx(&buf[..written], identity);
160 self.decrypter.assemble_records(self.identity.unwrap());
161 if let Err(e) = self.decrypter.decrypt_records(self.identity.unwrap()) {
162 if e.kind() != ErrorKind::UnexpectedEof {
163 panic!("unexpected error: {e}");
164 }
165 }
166
167 Ok(written)
168 }
169
170 fn flush(&mut self) -> std::io::Result<()> {
171 Ok(())
173 }
174}