1mod aead;
2mod alert;
3mod alpn;
4mod bffi_ext;
5mod client;
6mod error;
7mod handshake_token;
8mod hkdf;
9mod hmac;
10mod key;
11mod key_log;
12mod macros;
13mod retry;
14mod secret;
15mod server;
16mod session_cache;
17mod session_state;
18mod suite;
19mod version;
20
21pub use bffi_ext::*;
23pub use client::Config as ClientConfig;
24pub use error::{Error, Result};
25pub use handshake_token::HandshakeTokenKey;
26pub use hmac::HmacKey;
27pub use key_log::*;
28pub use server::Config as ServerConfig;
29pub use session_cache::*;
30pub use version::QuicVersion;
31
32#[derive(Clone, Debug)]
34pub struct HandshakeData {
35 pub protocol: Option<Vec<u8>>,
39
40 pub server_name: Option<String>,
44}
45
46pub mod helpers {
47 use super::*;
48 use quinn_proto::crypto;
49 use std::sync::Arc;
50
51 pub fn server_config(crypto: Arc<dyn crypto::ServerConfig>) -> Result<quinn::ServerConfig> {
55 Ok(quinn::ServerConfig::new(
56 crypto,
57 Arc::new(HandshakeTokenKey::new()?),
58 ))
59 }
60
61 pub fn default_endpoint_config() -> quinn::EndpointConfig {
63 let mut cfg = quinn::EndpointConfig::new(Arc::new(HmacKey::sha256()));
64 cfg.supported_versions(QuicVersion::default_supported_versions());
65 cfg
66 }
67
68 #[cfg(feature = "runtime-tokio")]
79 pub fn client_endpoint(addr: std::net::SocketAddr) -> std::io::Result<quinn::Endpoint> {
80 let socket = std::net::UdpSocket::bind(addr)?;
81 quinn::Endpoint::new(
82 default_endpoint_config(),
83 None,
84 socket,
85 Arc::new(quinn::TokioRuntime),
86 )
87 }
88
89 #[cfg(feature = "runtime-tokio")]
96 pub fn server_endpoint(
97 config: quinn::ServerConfig,
98 addr: std::net::SocketAddr,
99 ) -> std::io::Result<quinn::Endpoint> {
100 let socket = std::net::UdpSocket::bind(addr)?;
101 quinn::Endpoint::new(
102 default_endpoint_config(),
103 Some(config),
104 socket,
105 Arc::new(quinn::TokioRuntime),
106 )
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 use crate::error::Result;
115 use crate::secret::{Secret, Secrets};
116 use crate::suite::CipherSuite;
117 use bytes::BytesMut;
118 use hex_literal::hex;
119 use quinn_proto::crypto::PacketKey;
120 use quinn_proto::{ConnectionId, Side};
121
122 #[test]
124 fn test_initial_keys_v1() -> Result<()> {
125 let dcid: &[u8] = &hex!("8394c8f03e515708");
126 let version = QuicVersion::V1;
127 let suite = CipherSuite::aes128_gcm_sha256();
128
129 let s = Secrets::initial(version, &ConnectionId::new(dcid), Side::Client)?;
130
131 let expected_enc_key: &[u8] = &hex!("1f369613dd76d5467730efcbe3b1a22d");
132 assert_eq!(
133 s.local.packet_key(version, suite)?.key().slice(),
134 expected_enc_key
135 );
136 let expected_enc_iv: &[u8] = &hex!("fa044b2f42a3fd3b46fb255c");
137 assert_eq!(
138 s.local.packet_key(version, suite)?.iv().slice(),
139 expected_enc_iv
140 );
141 let expected_enc_hdr_key: &[u8] = &hex!("9f50449e04a0e810283a1e9933adedd2");
142 assert_eq!(
143 s.local.header_key(version, suite)?.key().slice(),
144 expected_enc_hdr_key
145 );
146 let expected_dec_key: &[u8] = &hex!("cf3a5331653c364c88f0f379b6067e37");
147 assert_eq!(
148 s.remote.packet_key(version, suite)?.key().slice(),
149 expected_dec_key
150 );
151 let expected_dec_iv: &[u8] = &hex!("0ac1493ca1905853b0bba03e");
152 assert_eq!(
153 s.remote.packet_key(version, suite)?.iv().slice(),
154 expected_dec_iv
155 );
156 let expected_dec_hdr_key: &[u8] = &hex!("c206b8d9b9f0f37644430b490eeaa314");
157 assert_eq!(
158 s.remote.header_key(version, suite)?.key().slice(),
159 expected_dec_hdr_key
160 );
161
162 Ok(())
163 }
164
165 #[test]
167 fn short_packet_header_protection() {
168 const PN: u64 = 654360564;
171 const SECRET: &[u8] =
172 &hex!("9ac312a7f877468ebe69422748ad00a15443f18203a07d6060f688f30f21632b");
173
174 let version = QuicVersion::V1;
175 let suite = CipherSuite::chacha20_poly1305_sha256();
176
177 let secret = Secret::from(SECRET);
178 let hpk = secret
179 .header_key(version, suite)
180 .unwrap()
181 .as_crypto()
182 .unwrap();
183 let packet = secret.packet_key(version, suite).unwrap();
184
185 const PLAIN: &[u8] = &[0x42, 0x00, 0xbf, 0xf4, b'h', b'e', b'l', b'l', b'o'];
186
187 let mut buf = PLAIN.to_vec();
188 buf.extend_from_slice(&[0u8; 16]);
190 packet.encrypt(PN, &mut buf, 4);
191
192 let pn_offset = 1;
193 hpk.encrypt(pn_offset, &mut buf);
194
195 const PROTECTED: &[u8] = &hex!("593b46220c4d504a9f1857793356400fc4a784ee309dff98b2");
196
197 assert_eq!(&buf, PROTECTED);
198
199 hpk.decrypt(pn_offset, &mut buf);
200
201 let (header, payload_tag) = buf.split_at(4);
202 let mut payload_tag = BytesMut::from(payload_tag);
203 packet.decrypt(PN, header, &mut payload_tag).unwrap();
204 let plain = payload_tag.as_ref();
205 assert_eq!(plain, &PLAIN[4..]);
206 }
207
208 #[test]
210 fn key_update_test_vector() {
211 let version = QuicVersion::V1;
212 let suite = CipherSuite::aes128_gcm_sha256();
213 let mut secrets = Secrets {
214 version,
215 suite,
216 local: Secret::from(&hex!(
217 "b8767708f8772358a6ea9fc43e4add2c961b3f5287a6d1467ee0aeab33724dbf"
218 )),
219 remote: Secret::from(&hex!(
220 "42dc972140e0f2e39845b767613439dc6758ca43259b878506824eb1e438d855"
221 )),
222 };
223 secrets.update().unwrap();
224
225 let expected = Secrets {
226 version,
227 suite,
228 local: Secret::from(&hex!(
229 "42cac8c91cd5eb40682e432edf2d2be9f41a52ca6b22d8e6cdb1e8aca9061fce"
230 )),
231 remote: Secret::from(&hex!(
232 "eb7f5e2a123f407db499e361cae590d4d992e14b7ace03c244e0422115b6d38a"
233 )),
234 };
235
236 assert_eq!(expected, secrets);
237 }
238
239 #[test]
240 fn client_encrypt_header() {
241 let dcid = ConnectionId::new(&hex!("06b858ec6f80452b"));
242
243 let secrets = Secrets::initial(QuicVersion::V1, &dcid, Side::Client).unwrap();
244 let client = secrets.keys().unwrap().as_crypto().unwrap();
245
246 let mut packet: [u8; 51] = hex!(
248 "c0000000010806b858ec6f80452b0000402100c8fb7ffd97230e38b70d86e7ff148afdf88fc21c4426c7d1cec79914c8785757"
249 );
250 let packet_number = 0;
251 let packet_number_pos = 18;
252 let header_len = 19;
253
254 client
256 .packet
257 .local
258 .encrypt(packet_number, &mut packet, header_len);
259 let expected_after_packet_encrypt: [u8; 51] = hex!(
260 "c0000000010806b858ec6f80452b0000402100f60e77fa2f629f9921fae64125c5632cf769d801a4693af6b949af37c2c45399"
261 );
262 assert_eq!(packet, expected_after_packet_encrypt);
263
264 client.header.local.encrypt(packet_number_pos, &mut packet);
266 let expected_after_header_encrypt: [u8; 51] = hex!(
267 "cd000000010806b858ec6f80452b000040210bf60e77fa2f629f9921fae64125c5632cf769d801a4693af6b949af37c2c45399"
268 );
269 assert_eq!(packet, expected_after_header_encrypt);
270 }
271
272 #[test]
273 fn server_decrypt_header() {
274 let dcid = ConnectionId::new(&hex!("06b858ec6f80452b"));
275 let secrets = Secrets::initial(QuicVersion::V1, &dcid, Side::Server).unwrap();
276 let server = secrets.keys().unwrap().as_crypto().unwrap();
277
278 let mut packet = BytesMut::from(&hex!(
279 "c8000000010806b858ec6f80452b00004021be3ef50807b84191a196f760a6dad1e9d1c430c48952cba0148250c21c0a6a70e1"
280 )[..]);
281 let packet_number = 0;
282 let packet_number_pos = 18;
283 let header_len = 19;
284
285 server.header.remote.decrypt(packet_number_pos, &mut packet);
287 let expected_header: [u8; 19] = hex!("c0000000010806b858ec6f80452b0000402100");
288 assert_eq!(packet[..header_len], expected_header);
289
290 let mut header = packet;
292 let mut packet = header.split_off(header_len);
293 server
294 .packet
295 .remote
296 .decrypt(packet_number, &header, &mut packet)
297 .unwrap();
298 assert_eq!(packet[..], [0; 16]);
299 }
300}