1use bytes::BytesMut;
2
3use noq_proto::{
4 ConnectionId, PathId, Side, TransportError,
5 crypto::{
6 self, CryptoError,
7 rustls::{QuicClientConfig, QuicServerConfig},
8 },
9 transport_parameters,
10};
11
12struct NoProtectionSession {
14 inner: Box<dyn crypto::Session>,
15}
16
17impl NoProtectionSession {
18 fn new(tls: Box<dyn crypto::Session>) -> Self {
19 Self { inner: tls }
20 }
21
22 fn wrap_packet_keys(
24 keys: crypto::KeyPair<Box<dyn crypto::PacketKey>>,
25 ) -> crypto::KeyPair<Box<dyn crypto::PacketKey>> {
26 crypto::KeyPair {
27 local: Box::new(NoProtectionPacketKey::new(keys.local)),
28 remote: Box::new(NoProtectionPacketKey::new(keys.remote)),
29 }
30 }
31}
32
33struct NoProtectionPacketKey {
34 inner: Box<dyn crypto::PacketKey>,
35}
36
37impl NoProtectionPacketKey {
38 fn new(key: Box<dyn crypto::PacketKey>) -> Self {
39 Self { inner: key }
40 }
41}
42
43#[derive(Clone)]
44pub struct NoProtectionClientConfig {
45 inner: QuicClientConfig,
46}
47
48impl NoProtectionClientConfig {
49 pub fn new(config: QuicClientConfig) -> Self {
50 Self { inner: config }
51 }
52}
53
54#[derive(Clone)]
55pub struct NoProtectionServerConfig {
56 inner: QuicServerConfig,
57}
58
59impl NoProtectionServerConfig {
60 pub fn new(config: QuicServerConfig) -> Self {
61 Self { inner: config }
62 }
63}
64
65impl crypto::Session for NoProtectionSession {
67 fn initial_keys(&self, dst_cid: ConnectionId, side: Side) -> crypto::Keys {
68 self.inner.initial_keys(dst_cid, side)
69 }
70
71 fn handshake_data(&self) -> Option<Box<dyn std::any::Any>> {
72 self.inner.handshake_data()
73 }
74
75 fn peer_identity(&self) -> Option<Box<dyn std::any::Any>> {
76 self.inner.peer_identity()
77 }
78
79 fn early_crypto(&self) -> Option<(Box<dyn crypto::HeaderKey>, Box<dyn crypto::PacketKey>)> {
80 let (hkey, pkey) = self.inner.early_crypto()?;
81
82 Some((hkey, Box::new(NoProtectionPacketKey::new(pkey))))
84 }
85
86 fn early_data_accepted(&self) -> Option<bool> {
87 self.inner.early_data_accepted()
88 }
89
90 fn is_handshaking(&self) -> bool {
91 self.inner.is_handshaking()
92 }
93
94 fn read_handshake(&mut self, buf: &[u8]) -> Result<bool, TransportError> {
95 self.inner.read_handshake(buf)
96 }
97
98 fn transport_parameters(
99 &self,
100 ) -> Result<Option<transport_parameters::TransportParameters>, TransportError> {
101 self.inner.transport_parameters()
102 }
103
104 fn write_handshake(&mut self, buf: &mut Vec<u8>) -> Option<crypto::Keys> {
105 let keys = self.inner.write_handshake(buf)?;
106
107 Some(crypto::Keys {
108 header: keys.header,
109 packet: Self::wrap_packet_keys(keys.packet),
110 })
111 }
112
113 fn next_1rtt_keys(&mut self) -> Option<crypto::KeyPair<Box<dyn crypto::PacketKey>>> {
114 let keys = self.inner.next_1rtt_keys()?;
115 Some(Self::wrap_packet_keys(keys))
116 }
117
118 fn is_valid_retry(&self, orig_dst_cid: ConnectionId, header: &[u8], payload: &[u8]) -> bool {
119 self.inner.is_valid_retry(orig_dst_cid, header, payload)
120 }
121
122 fn export_keying_material(
123 &self,
124 output: &mut [u8],
125 label: &[u8],
126 context: &[u8],
127 ) -> Result<(), crypto::ExportKeyingMaterialError> {
128 self.inner.export_keying_material(output, label, context)
129 }
130}
131
132impl crypto::ClientConfig for NoProtectionClientConfig {
133 fn start_session(
134 &self,
135 version: u32,
136 server_name: &str,
137 params: &transport_parameters::TransportParameters,
138 ) -> Result<Box<dyn crypto::Session>, noq::ConnectError> {
139 let tls = self
140 .inner
141 .clone()
142 .start_session(version, server_name, params)?;
143
144 Ok(Box::new(NoProtectionSession::new(tls)))
145 }
146}
147
148impl crypto::ServerConfig for NoProtectionServerConfig {
149 fn initial_keys(
150 &self,
151 version: u32,
152 dst_cid: ConnectionId,
153 ) -> Result<crypto::Keys, crypto::UnsupportedVersion> {
154 self.inner.initial_keys(version, dst_cid)
155 }
156
157 fn retry_tag(&self, version: u32, orig_dst_cid: ConnectionId, packet: &[u8]) -> [u8; 16] {
158 self.inner.retry_tag(version, orig_dst_cid, packet)
159 }
160
161 fn start_session(
162 &self,
163 version: u32,
164 params: &transport_parameters::TransportParameters,
165 ) -> Box<dyn crypto::Session> {
166 let tls = self.inner.start_session(version, params);
167
168 Box::new(NoProtectionSession::new(tls))
169 }
170}
171
172impl crypto::PacketKey for NoProtectionPacketKey {
174 fn encrypt(&self, _path_id: PathId, _packet: u64, buf: &mut [u8], header_len: usize) {
175 let (_header, payload_tag) = buf.split_at_mut(header_len);
176 let (_payload, tag_storage) =
177 payload_tag.split_at_mut(payload_tag.len() - self.inner.tag_len());
178 tag_storage.fill(42);
180 }
181
182 fn decrypt(
183 &self,
184 _path_id: PathId,
185 _packet: u64,
186 _header: &[u8],
187 payload: &mut BytesMut,
188 ) -> Result<(), CryptoError> {
189 let plain_len = payload.len() - self.inner.tag_len();
190 payload.truncate(plain_len);
191 Ok(())
192 }
193
194 fn tag_len(&self) -> usize {
195 self.inner.tag_len()
196 }
197
198 fn confidentiality_limit(&self) -> u64 {
199 self.inner.confidentiality_limit()
200 }
201
202 fn integrity_limit(&self) -> u64 {
203 self.inner.integrity_limit()
204 }
205}