1use crate::client::{ClientConfig, ClientConnectionData};
3use crate::common_state::{CommonState, Protocol, Side};
4use crate::conn::{ConnectionCore, SideData};
5use crate::crypto::cipher::{AeadKey, Iv};
6use crate::crypto::tls13::{Hkdf, HkdfExpander, OkmBlock};
7use crate::enums::{AlertDescription, ProtocolVersion};
8use crate::error::Error;
9use crate::msgs::handshake::{ClientExtension, ServerExtension};
10use crate::server::{ServerConfig, ServerConnectionData};
11use crate::tls13::key_schedule::{
12 hkdf_expand_label, hkdf_expand_label_aead_key, hkdf_expand_label_block,
13};
14use crate::tls13::Tls13CipherSuite;
15
16use pki_types::ServerName;
17
18use alloc::boxed::Box;
19use alloc::collections::VecDeque;
20use alloc::sync::Arc;
21use alloc::vec;
22use alloc::vec::Vec;
23use core::fmt::{self, Debug};
24use core::ops::{Deref, DerefMut};
25
26#[derive(Debug)]
28pub enum Connection {
29 Client(ClientConnection),
31 Server(ServerConnection),
33}
34
35impl Connection {
36 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
40 match self {
41 Self::Client(conn) => conn.quic_transport_parameters(),
42 Self::Server(conn) => conn.quic_transport_parameters(),
43 }
44 }
45
46 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
48 match self {
49 Self::Client(conn) => conn.zero_rtt_keys(),
50 Self::Server(conn) => conn.zero_rtt_keys(),
51 }
52 }
53
54 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
58 match self {
59 Self::Client(conn) => conn.read_hs(plaintext),
60 Self::Server(conn) => conn.read_hs(plaintext),
61 }
62 }
63
64 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
68 match self {
69 Self::Client(conn) => conn.write_hs(buf),
70 Self::Server(conn) => conn.write_hs(buf),
71 }
72 }
73
74 pub fn alert(&self) -> Option<AlertDescription> {
78 match self {
79 Self::Client(conn) => conn.alert(),
80 Self::Server(conn) => conn.alert(),
81 }
82 }
83
84 #[inline]
100 pub fn export_keying_material<T: AsMut<[u8]>>(
101 &self,
102 output: T,
103 label: &[u8],
104 context: Option<&[u8]>,
105 ) -> Result<T, Error> {
106 match self {
107 Self::Client(conn) => conn
108 .core
109 .export_keying_material(output, label, context),
110 Self::Server(conn) => conn
111 .core
112 .export_keying_material(output, label, context),
113 }
114 }
115}
116
117impl Deref for Connection {
118 type Target = CommonState;
119
120 fn deref(&self) -> &Self::Target {
121 match self {
122 Self::Client(conn) => &conn.core.common_state,
123 Self::Server(conn) => &conn.core.common_state,
124 }
125 }
126}
127
128impl DerefMut for Connection {
129 fn deref_mut(&mut self) -> &mut Self::Target {
130 match self {
131 Self::Client(conn) => &mut conn.core.common_state,
132 Self::Server(conn) => &mut conn.core.common_state,
133 }
134 }
135}
136
137pub struct ClientConnection {
139 inner: ConnectionCommon<ClientConnectionData>,
140}
141
142impl ClientConnection {
143 pub fn new(
148 config: Arc<ClientConfig>,
149 quic_version: Version,
150 name: ServerName<'static>,
151 params: Vec<u8>,
152 ) -> Result<Self, Error> {
153 if !config.supports_version(ProtocolVersion::TLSv1_3) {
154 return Err(Error::General(
155 "TLS 1.3 support is required for QUIC".into(),
156 ));
157 }
158
159 if !config.supports_protocol(Protocol::Quic) {
160 return Err(Error::General(
161 "at least one ciphersuite must support QUIC".into(),
162 ));
163 }
164
165 let ext = match quic_version {
166 Version::V1Draft => ClientExtension::TransportParametersDraft(params),
167 Version::V1 | Version::V2 => ClientExtension::TransportParameters(params),
168 };
169
170 let mut inner = ConnectionCore::for_client(config, name, vec![ext], Protocol::Quic)?;
171 inner.common_state.quic.version = quic_version;
172 Ok(Self {
173 inner: inner.into(),
174 })
175 }
176
177 pub fn is_early_data_accepted(&self) -> bool {
183 self.inner.core.is_early_data_accepted()
184 }
185}
186
187impl Deref for ClientConnection {
188 type Target = ConnectionCommon<ClientConnectionData>;
189
190 fn deref(&self) -> &Self::Target {
191 &self.inner
192 }
193}
194
195impl DerefMut for ClientConnection {
196 fn deref_mut(&mut self) -> &mut Self::Target {
197 &mut self.inner
198 }
199}
200
201impl Debug for ClientConnection {
202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203 f.debug_struct("quic::ClientConnection")
204 .finish()
205 }
206}
207
208impl From<ClientConnection> for Connection {
209 fn from(c: ClientConnection) -> Self {
210 Self::Client(c)
211 }
212}
213
214pub struct ServerConnection {
216 inner: ConnectionCommon<ServerConnectionData>,
217}
218
219impl ServerConnection {
220 pub fn new(
225 config: Arc<ServerConfig>,
226 quic_version: Version,
227 params: Vec<u8>,
228 ) -> Result<Self, Error> {
229 if !config.supports_version(ProtocolVersion::TLSv1_3) {
230 return Err(Error::General(
231 "TLS 1.3 support is required for QUIC".into(),
232 ));
233 }
234
235 if !config.supports_protocol(Protocol::Quic) {
236 return Err(Error::General(
237 "at least one ciphersuite must support QUIC".into(),
238 ));
239 }
240
241 if config.max_early_data_size != 0 && config.max_early_data_size != 0xffff_ffff {
242 return Err(Error::General(
243 "QUIC sessions must set a max early data of 0 or 2^32-1".into(),
244 ));
245 }
246
247 let ext = match quic_version {
248 Version::V1Draft => ServerExtension::TransportParametersDraft(params),
249 Version::V1 | Version::V2 => ServerExtension::TransportParameters(params),
250 };
251
252 let mut core = ConnectionCore::for_server(config, vec![ext])?;
253 core.common_state.protocol = Protocol::Quic;
254 core.common_state.quic.version = quic_version;
255 Ok(Self { inner: core.into() })
256 }
257
258 pub fn reject_early_data(&mut self) {
264 self.inner.core.reject_early_data()
265 }
266
267 pub fn server_name(&self) -> Option<&str> {
283 self.inner.core.get_sni_str()
284 }
285}
286
287impl Deref for ServerConnection {
288 type Target = ConnectionCommon<ServerConnectionData>;
289
290 fn deref(&self) -> &Self::Target {
291 &self.inner
292 }
293}
294
295impl DerefMut for ServerConnection {
296 fn deref_mut(&mut self) -> &mut Self::Target {
297 &mut self.inner
298 }
299}
300
301impl Debug for ServerConnection {
302 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
303 f.debug_struct("quic::ServerConnection")
304 .finish()
305 }
306}
307
308impl From<ServerConnection> for Connection {
309 fn from(c: ServerConnection) -> Self {
310 Self::Server(c)
311 }
312}
313
314pub struct ConnectionCommon<Data> {
316 core: ConnectionCore<Data>,
317}
318
319impl<Data: SideData> ConnectionCommon<Data> {
320 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
328 self.core
329 .common_state
330 .quic
331 .params
332 .as_ref()
333 .map(|v| v.as_ref())
334 }
335
336 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
338 let suite = self
339 .core
340 .common_state
341 .suite
342 .and_then(|suite| suite.tls13())?;
343 Some(DirectionalKeys::new(
344 suite,
345 suite.quic?,
346 self.core
347 .common_state
348 .quic
349 .early_secret
350 .as_ref()?,
351 self.core.common_state.quic.version,
352 ))
353 }
354
355 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
359 self.core
360 .message_deframer
361 .push(ProtocolVersion::TLSv1_3, plaintext)?;
362 self.core.process_new_packets()?;
363 Ok(())
364 }
365
366 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
370 self.core
371 .common_state
372 .quic
373 .write_hs(buf)
374 }
375
376 pub fn alert(&self) -> Option<AlertDescription> {
380 self.core.common_state.quic.alert
381 }
382}
383
384impl<Data> Deref for ConnectionCommon<Data> {
385 type Target = CommonState;
386
387 fn deref(&self) -> &Self::Target {
388 &self.core.common_state
389 }
390}
391
392impl<Data> DerefMut for ConnectionCommon<Data> {
393 fn deref_mut(&mut self) -> &mut Self::Target {
394 &mut self.core.common_state
395 }
396}
397
398impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
399 fn from(core: ConnectionCore<Data>) -> Self {
400 Self { core }
401 }
402}
403
404#[derive(Default)]
405pub(crate) struct Quic {
406 pub(crate) params: Option<Vec<u8>>,
408 pub(crate) alert: Option<AlertDescription>,
409 pub(crate) hs_queue: VecDeque<(bool, Vec<u8>)>,
410 pub(crate) early_secret: Option<OkmBlock>,
411 pub(crate) hs_secrets: Option<Secrets>,
412 pub(crate) traffic_secrets: Option<Secrets>,
413 pub(crate) returned_traffic_keys: bool,
415 pub(crate) version: Version,
416}
417
418impl Quic {
419 pub(crate) fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
420 while let Some((_, msg)) = self.hs_queue.pop_front() {
421 buf.extend_from_slice(&msg);
422 if let Some(&(true, _)) = self.hs_queue.front() {
423 if self.hs_secrets.is_some() {
424 break;
426 }
427 }
428 }
429
430 if let Some(secrets) = self.hs_secrets.take() {
431 return Some(KeyChange::Handshake {
432 keys: Keys::new(&secrets),
433 });
434 }
435
436 if let Some(mut secrets) = self.traffic_secrets.take() {
437 if !self.returned_traffic_keys {
438 self.returned_traffic_keys = true;
439 let keys = Keys::new(&secrets);
440 secrets.update();
441 return Some(KeyChange::OneRtt {
442 keys,
443 next: secrets,
444 });
445 }
446 }
447
448 None
449 }
450}
451
452#[derive(Clone)]
454pub struct Secrets {
455 pub(crate) client: OkmBlock,
457 pub(crate) server: OkmBlock,
459 suite: &'static Tls13CipherSuite,
461 quic: &'static dyn Algorithm,
462 side: Side,
463 version: Version,
464}
465
466impl Secrets {
467 pub(crate) fn new(
468 client: OkmBlock,
469 server: OkmBlock,
470 suite: &'static Tls13CipherSuite,
471 quic: &'static dyn Algorithm,
472 side: Side,
473 version: Version,
474 ) -> Self {
475 Self {
476 client,
477 server,
478 suite,
479 quic,
480 side,
481 version,
482 }
483 }
484
485 pub fn next_packet_keys(&mut self) -> PacketKeySet {
487 let keys = PacketKeySet::new(self);
488 self.update();
489 keys
490 }
491
492 pub(crate) fn update(&mut self) {
493 self.client = hkdf_expand_label_block(
494 self.suite
495 .hkdf_provider
496 .expander_for_okm(&self.client)
497 .as_ref(),
498 self.version.key_update_label(),
499 &[],
500 );
501 self.server = hkdf_expand_label_block(
502 self.suite
503 .hkdf_provider
504 .expander_for_okm(&self.server)
505 .as_ref(),
506 self.version.key_update_label(),
507 &[],
508 );
509 }
510
511 fn local_remote(&self) -> (&OkmBlock, &OkmBlock) {
512 match self.side {
513 Side::Client => (&self.client, &self.server),
514 Side::Server => (&self.server, &self.client),
515 }
516 }
517}
518
519pub struct DirectionalKeys {
521 pub header: Box<dyn HeaderProtectionKey>,
523 pub packet: Box<dyn PacketKey>,
525}
526
527impl DirectionalKeys {
528 pub(crate) fn new(
529 suite: &'static Tls13CipherSuite,
530 quic: &'static dyn Algorithm,
531 secret: &OkmBlock,
532 version: Version,
533 ) -> Self {
534 let builder = KeyBuilder::new(secret, version, quic, suite.hkdf_provider);
535 Self {
536 header: builder.header_protection_key(),
537 packet: builder.packet_key(),
538 }
539 }
540}
541
542const TAG_LEN: usize = 16;
544
545pub struct Tag([u8; TAG_LEN]);
547
548impl From<&[u8]> for Tag {
549 fn from(value: &[u8]) -> Self {
550 let mut array = [0u8; TAG_LEN];
551 array.copy_from_slice(value);
552 Self(array)
553 }
554}
555
556impl AsRef<[u8]> for Tag {
557 fn as_ref(&self) -> &[u8] {
558 &self.0
559 }
560}
561
562pub trait Algorithm: Send + Sync {
564 fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn PacketKey>;
569
570 fn header_protection_key(&self, key: AeadKey) -> Box<dyn HeaderProtectionKey>;
574
575 fn aead_key_len(&self) -> usize;
579}
580
581pub trait HeaderProtectionKey {
583 fn encrypt_in_place(
604 &self,
605 sample: &[u8],
606 first: &mut u8,
607 packet_number: &mut [u8],
608 ) -> Result<(), Error>;
609
610 fn decrypt_in_place(
632 &self,
633 sample: &[u8],
634 first: &mut u8,
635 packet_number: &mut [u8],
636 ) -> Result<(), Error>;
637
638 fn sample_len(&self) -> usize;
640}
641
642pub trait PacketKey {
644 fn encrypt_in_place(
652 &self,
653 packet_number: u64,
654 header: &[u8],
655 payload: &mut [u8],
656 ) -> Result<Tag, Error>;
657
658 fn decrypt_in_place<'a>(
666 &self,
667 packet_number: u64,
668 header: &[u8],
669 payload: &'a mut [u8],
670 ) -> Result<&'a [u8], Error>;
671
672 fn tag_len(&self) -> usize;
674}
675
676pub struct PacketKeySet {
678 pub local: Box<dyn PacketKey>,
680 pub remote: Box<dyn PacketKey>,
682}
683
684impl PacketKeySet {
685 fn new(secrets: &Secrets) -> Self {
686 let (local, remote) = secrets.local_remote();
687 let (version, alg, hkdf) = (secrets.version, secrets.quic, secrets.suite.hkdf_provider);
688 Self {
689 local: KeyBuilder::new(local, version, alg, hkdf).packet_key(),
690 remote: KeyBuilder::new(remote, version, alg, hkdf).packet_key(),
691 }
692 }
693}
694
695pub(crate) struct KeyBuilder<'a> {
696 expander: Box<dyn HkdfExpander>,
697 version: Version,
698 alg: &'a dyn Algorithm,
699}
700
701impl<'a> KeyBuilder<'a> {
702 pub(crate) fn new(
703 secret: &OkmBlock,
704 version: Version,
705 alg: &'a dyn Algorithm,
706 hkdf: &'a dyn Hkdf,
707 ) -> Self {
708 Self {
709 expander: hkdf.expander_for_okm(secret),
710 version,
711 alg,
712 }
713 }
714
715 pub(crate) fn packet_key(&self) -> Box<dyn PacketKey> {
717 let aead_key_len = self.alg.aead_key_len();
718 let packet_key = hkdf_expand_label_aead_key(
719 self.expander.as_ref(),
720 aead_key_len,
721 self.version.packet_key_label(),
722 &[],
723 );
724
725 let packet_iv =
726 hkdf_expand_label(self.expander.as_ref(), self.version.packet_iv_label(), &[]);
727 self.alg
728 .packet_key(packet_key, packet_iv)
729 }
730
731 pub(crate) fn header_protection_key(&self) -> Box<dyn HeaderProtectionKey> {
733 let header_key = hkdf_expand_label_aead_key(
734 self.expander.as_ref(),
735 self.alg.aead_key_len(),
736 self.version.header_key_label(),
737 &[],
738 );
739 self.alg
740 .header_protection_key(header_key)
741 }
742}
743
744pub struct Keys {
746 pub local: DirectionalKeys,
748 pub remote: DirectionalKeys,
750}
751
752impl Keys {
753 pub fn initial(
755 version: Version,
756 suite: &'static Tls13CipherSuite,
757 quic: &'static dyn Algorithm,
758 client_dst_connection_id: &[u8],
759 side: Side,
760 ) -> Self {
761 const CLIENT_LABEL: &[u8] = b"client in";
762 const SERVER_LABEL: &[u8] = b"server in";
763 let salt = version.initial_salt();
764 let hs_secret = suite
765 .hkdf_provider
766 .extract_from_secret(Some(salt), client_dst_connection_id);
767
768 let secrets = Secrets {
769 version,
770 client: hkdf_expand_label_block(hs_secret.as_ref(), CLIENT_LABEL, &[]),
771 server: hkdf_expand_label_block(hs_secret.as_ref(), SERVER_LABEL, &[]),
772 suite,
773 quic,
774 side,
775 };
776 Self::new(&secrets)
777 }
778
779 fn new(secrets: &Secrets) -> Self {
780 let (local, remote) = secrets.local_remote();
781 Self {
782 local: DirectionalKeys::new(secrets.suite, secrets.quic, local, secrets.version),
783 remote: DirectionalKeys::new(secrets.suite, secrets.quic, remote, secrets.version),
784 }
785 }
786}
787
788#[allow(clippy::large_enum_variant)]
802pub enum KeyChange {
803 Handshake {
805 keys: Keys,
807 },
808 OneRtt {
810 keys: Keys,
812 next: Secrets,
814 },
815}
816
817#[non_exhaustive]
821#[derive(Clone, Copy, Debug)]
822pub enum Version {
823 V1Draft,
825 V1,
827 V2,
829}
830
831impl Version {
832 fn initial_salt(self) -> &'static [u8; 20] {
833 match self {
834 Self::V1Draft => &[
835 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
837 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
838 ],
839 Self::V1 => &[
840 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
842 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
843 ],
844 Self::V2 => &[
845 0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26,
847 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9,
848 ],
849 }
850 }
851
852 pub(crate) fn packet_key_label(&self) -> &'static [u8] {
854 match self {
855 Self::V1Draft | Self::V1 => b"quic key",
856 Self::V2 => b"quicv2 key",
857 }
858 }
859
860 pub(crate) fn packet_iv_label(&self) -> &'static [u8] {
862 match self {
863 Self::V1Draft | Self::V1 => b"quic iv",
864 Self::V2 => b"quicv2 iv",
865 }
866 }
867
868 pub(crate) fn header_key_label(&self) -> &'static [u8] {
870 match self {
871 Self::V1Draft | Self::V1 => b"quic hp",
872 Self::V2 => b"quicv2 hp",
873 }
874 }
875
876 fn key_update_label(&self) -> &'static [u8] {
877 match self {
878 Self::V1Draft | Self::V1 => b"quic ku",
879 Self::V2 => b"quicv2 ku",
880 }
881 }
882}
883
884impl Default for Version {
885 fn default() -> Self {
886 Self::V1
887 }
888}