1use alloc::boxed::Box;
2use alloc::collections::VecDeque;
3use alloc::vec::Vec;
4#[cfg(feature = "std")]
5use core::fmt::Debug;
6
7use crate::common_state::Side;
9use crate::crypto::cipher::{AeadKey, Iv};
10use crate::crypto::tls13::{Hkdf, HkdfExpander, OkmBlock};
11use crate::enums::AlertDescription;
12use crate::error::Error;
13use crate::tls13::key_schedule::{
14 hkdf_expand_label, hkdf_expand_label_aead_key, hkdf_expand_label_block,
15};
16use crate::tls13::Tls13CipherSuite;
17
18#[cfg(feature = "std")]
19mod connection {
20 use alloc::sync::Arc;
21 use alloc::vec;
22 use alloc::vec::Vec;
23 use core::fmt::{self, Debug};
24 use core::ops::{Deref, DerefMut};
25
26 use pki_types::ServerName;
27
28 use super::{DirectionalKeys, KeyChange, Version};
29 use crate::client::{ClientConfig, ClientConnectionData};
30 use crate::common_state::{CommonState, Protocol, DEFAULT_BUFFER_LIMIT};
31 use crate::conn::{ConnectionCore, SideData};
32 use crate::enums::{AlertDescription, ProtocolVersion};
33 use crate::error::Error;
34 use crate::msgs::deframer::DeframerVecBuffer;
35 use crate::msgs::handshake::{ClientExtension, ServerExtension};
36 use crate::server::{ServerConfig, ServerConnectionData};
37 use crate::vecbuf::ChunkVecBuffer;
38
39 #[derive(Debug)]
41 pub enum Connection {
42 Client(ClientConnection),
44 Server(ServerConnection),
46 }
47
48 impl Connection {
49 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
53 match self {
54 Self::Client(conn) => conn.quic_transport_parameters(),
55 Self::Server(conn) => conn.quic_transport_parameters(),
56 }
57 }
58
59 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
61 match self {
62 Self::Client(conn) => conn.zero_rtt_keys(),
63 Self::Server(conn) => conn.zero_rtt_keys(),
64 }
65 }
66
67 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
71 match self {
72 Self::Client(conn) => conn.read_hs(plaintext),
73 Self::Server(conn) => conn.read_hs(plaintext),
74 }
75 }
76
77 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
81 match self {
82 Self::Client(conn) => conn.write_hs(buf),
83 Self::Server(conn) => conn.write_hs(buf),
84 }
85 }
86
87 pub fn alert(&self) -> Option<AlertDescription> {
91 match self {
92 Self::Client(conn) => conn.alert(),
93 Self::Server(conn) => conn.alert(),
94 }
95 }
96
97 #[inline]
113 pub fn export_keying_material<T: AsMut<[u8]>>(
114 &self,
115 output: T,
116 label: &[u8],
117 context: Option<&[u8]>,
118 ) -> Result<T, Error> {
119 match self {
120 Self::Client(conn) => conn
121 .core
122 .export_keying_material(output, label, context),
123 Self::Server(conn) => conn
124 .core
125 .export_keying_material(output, label, context),
126 }
127 }
128 }
129
130 impl Deref for Connection {
131 type Target = CommonState;
132
133 fn deref(&self) -> &Self::Target {
134 match self {
135 Self::Client(conn) => &conn.core.common_state,
136 Self::Server(conn) => &conn.core.common_state,
137 }
138 }
139 }
140
141 impl DerefMut for Connection {
142 fn deref_mut(&mut self) -> &mut Self::Target {
143 match self {
144 Self::Client(conn) => &mut conn.core.common_state,
145 Self::Server(conn) => &mut conn.core.common_state,
146 }
147 }
148 }
149
150 pub struct ClientConnection {
152 inner: ConnectionCommon<ClientConnectionData>,
153 }
154
155 impl ClientConnection {
156 pub fn new(
161 config: Arc<ClientConfig>,
162 quic_version: Version,
163 name: ServerName<'static>,
164 params: Vec<u8>,
165 ) -> Result<Self, Error> {
166 if !config.supports_version(ProtocolVersion::TLSv1_3) {
167 return Err(Error::General(
168 "TLS 1.3 support is required for QUIC".into(),
169 ));
170 }
171
172 if !config.supports_protocol(Protocol::Quic) {
173 return Err(Error::General(
174 "at least one ciphersuite must support QUIC".into(),
175 ));
176 }
177
178 let ext = match quic_version {
179 Version::V1Draft => ClientExtension::TransportParametersDraft(params),
180 Version::V1 | Version::V2 => ClientExtension::TransportParameters(params),
181 };
182
183 let mut inner = ConnectionCore::for_client(config, name, vec![ext], Protocol::Quic)?;
184 inner.common_state.quic.version = quic_version;
185 Ok(Self {
186 inner: inner.into(),
187 })
188 }
189
190 pub fn is_early_data_accepted(&self) -> bool {
196 self.inner.core.is_early_data_accepted()
197 }
198 }
199
200 impl Deref for ClientConnection {
201 type Target = ConnectionCommon<ClientConnectionData>;
202
203 fn deref(&self) -> &Self::Target {
204 &self.inner
205 }
206 }
207
208 impl DerefMut for ClientConnection {
209 fn deref_mut(&mut self) -> &mut Self::Target {
210 &mut self.inner
211 }
212 }
213
214 impl Debug for ClientConnection {
215 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
216 f.debug_struct("quic::ClientConnection")
217 .finish()
218 }
219 }
220
221 impl From<ClientConnection> for Connection {
222 fn from(c: ClientConnection) -> Self {
223 Self::Client(c)
224 }
225 }
226
227 pub struct ServerConnection {
229 inner: ConnectionCommon<ServerConnectionData>,
230 }
231
232 impl ServerConnection {
233 pub fn new(
238 config: Arc<ServerConfig>,
239 quic_version: Version,
240 params: Vec<u8>,
241 ) -> Result<Self, Error> {
242 if !config.supports_version(ProtocolVersion::TLSv1_3) {
243 return Err(Error::General(
244 "TLS 1.3 support is required for QUIC".into(),
245 ));
246 }
247
248 if !config.supports_protocol(Protocol::Quic) {
249 return Err(Error::General(
250 "at least one ciphersuite must support QUIC".into(),
251 ));
252 }
253
254 if config.max_early_data_size != 0 && config.max_early_data_size != 0xffff_ffff {
255 return Err(Error::General(
256 "QUIC sessions must set a max early data of 0 or 2^32-1".into(),
257 ));
258 }
259
260 let ext = match quic_version {
261 Version::V1Draft => ServerExtension::TransportParametersDraft(params),
262 Version::V1 | Version::V2 => ServerExtension::TransportParameters(params),
263 };
264
265 let mut core = ConnectionCore::for_server(config, vec![ext])?;
266 core.common_state.protocol = Protocol::Quic;
267 core.common_state.quic.version = quic_version;
268 Ok(Self { inner: core.into() })
269 }
270
271 pub fn reject_early_data(&mut self) {
277 self.inner.core.reject_early_data()
278 }
279
280 pub fn server_name(&self) -> Option<&str> {
296 self.inner.core.get_sni_str()
297 }
298 }
299
300 impl Deref for ServerConnection {
301 type Target = ConnectionCommon<ServerConnectionData>;
302
303 fn deref(&self) -> &Self::Target {
304 &self.inner
305 }
306 }
307
308 impl DerefMut for ServerConnection {
309 fn deref_mut(&mut self) -> &mut Self::Target {
310 &mut self.inner
311 }
312 }
313
314 impl Debug for ServerConnection {
315 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
316 f.debug_struct("quic::ServerConnection")
317 .finish()
318 }
319 }
320
321 impl From<ServerConnection> for Connection {
322 fn from(c: ServerConnection) -> Self {
323 Self::Server(c)
324 }
325 }
326
327 pub struct ConnectionCommon<Data> {
329 core: ConnectionCore<Data>,
330 deframer_buffer: DeframerVecBuffer,
331 sendable_plaintext: ChunkVecBuffer,
332 }
333
334 impl<Data: SideData> ConnectionCommon<Data> {
335 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
343 self.core
344 .common_state
345 .quic
346 .params
347 .as_ref()
348 .map(|v| v.as_ref())
349 }
350
351 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
353 let suite = self
354 .core
355 .common_state
356 .suite
357 .and_then(|suite| suite.tls13())?;
358 Some(DirectionalKeys::new(
359 suite,
360 suite.quic?,
361 self.core
362 .common_state
363 .quic
364 .early_secret
365 .as_ref()?,
366 self.core.common_state.quic.version,
367 ))
368 }
369
370 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
374 self.core.message_deframer.push(
375 ProtocolVersion::TLSv1_3,
376 plaintext,
377 &mut self.deframer_buffer,
378 )?;
379 self.core
380 .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)?;
381 Ok(())
382 }
383
384 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
388 self.core
389 .common_state
390 .quic
391 .write_hs(buf)
392 }
393
394 pub fn alert(&self) -> Option<AlertDescription> {
398 self.core.common_state.quic.alert
399 }
400 }
401
402 impl<Data> Deref for ConnectionCommon<Data> {
403 type Target = CommonState;
404
405 fn deref(&self) -> &Self::Target {
406 &self.core.common_state
407 }
408 }
409
410 impl<Data> DerefMut for ConnectionCommon<Data> {
411 fn deref_mut(&mut self) -> &mut Self::Target {
412 &mut self.core.common_state
413 }
414 }
415
416 impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
417 fn from(core: ConnectionCore<Data>) -> Self {
418 Self {
419 core,
420 deframer_buffer: DeframerVecBuffer::default(),
421 sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
422 }
423 }
424 }
425}
426
427#[cfg(feature = "std")]
428pub use connection::{ClientConnection, Connection, ConnectionCommon, ServerConnection};
429
430#[derive(Default)]
431pub(crate) struct Quic {
432 pub(crate) params: Option<Vec<u8>>,
434 pub(crate) alert: Option<AlertDescription>,
435 pub(crate) hs_queue: VecDeque<(bool, Vec<u8>)>,
436 pub(crate) early_secret: Option<OkmBlock>,
437 pub(crate) hs_secrets: Option<Secrets>,
438 pub(crate) traffic_secrets: Option<Secrets>,
439 #[cfg(feature = "std")]
441 pub(crate) returned_traffic_keys: bool,
442 pub(crate) version: Version,
443}
444
445#[cfg(feature = "std")]
446impl Quic {
447 pub(crate) fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
448 while let Some((_, msg)) = self.hs_queue.pop_front() {
449 buf.extend_from_slice(&msg);
450 if let Some(&(true, _)) = self.hs_queue.front() {
451 if self.hs_secrets.is_some() {
452 break;
454 }
455 }
456 }
457
458 if let Some(secrets) = self.hs_secrets.take() {
459 return Some(KeyChange::Handshake {
460 keys: Keys::new(&secrets),
461 });
462 }
463
464 if let Some(mut secrets) = self.traffic_secrets.take() {
465 if !self.returned_traffic_keys {
466 self.returned_traffic_keys = true;
467 let keys = Keys::new(&secrets);
468 secrets.update();
469 return Some(KeyChange::OneRtt {
470 keys,
471 next: secrets,
472 });
473 }
474 }
475
476 None
477 }
478}
479
480#[derive(Clone)]
482pub struct Secrets {
483 pub(crate) client: OkmBlock,
485 pub(crate) server: OkmBlock,
487 suite: &'static Tls13CipherSuite,
489 quic: &'static dyn Algorithm,
490 side: Side,
491 version: Version,
492}
493
494impl Secrets {
495 pub(crate) fn new(
496 client: OkmBlock,
497 server: OkmBlock,
498 suite: &'static Tls13CipherSuite,
499 quic: &'static dyn Algorithm,
500 side: Side,
501 version: Version,
502 ) -> Self {
503 Self {
504 client,
505 server,
506 suite,
507 quic,
508 side,
509 version,
510 }
511 }
512
513 pub fn next_packet_keys(&mut self) -> PacketKeySet {
515 let keys = PacketKeySet::new(self);
516 self.update();
517 keys
518 }
519
520 pub(crate) fn update(&mut self) {
521 self.client = hkdf_expand_label_block(
522 self.suite
523 .hkdf_provider
524 .expander_for_okm(&self.client)
525 .as_ref(),
526 self.version.key_update_label(),
527 &[],
528 );
529 self.server = hkdf_expand_label_block(
530 self.suite
531 .hkdf_provider
532 .expander_for_okm(&self.server)
533 .as_ref(),
534 self.version.key_update_label(),
535 &[],
536 );
537 }
538
539 fn local_remote(&self) -> (&OkmBlock, &OkmBlock) {
540 match self.side {
541 Side::Client => (&self.client, &self.server),
542 Side::Server => (&self.server, &self.client),
543 }
544 }
545}
546
547pub struct DirectionalKeys {
549 pub header: Box<dyn HeaderProtectionKey>,
551 pub packet: Box<dyn PacketKey>,
553}
554
555impl DirectionalKeys {
556 pub(crate) fn new(
557 suite: &'static Tls13CipherSuite,
558 quic: &'static dyn Algorithm,
559 secret: &OkmBlock,
560 version: Version,
561 ) -> Self {
562 let builder = KeyBuilder::new(secret, version, quic, suite.hkdf_provider);
563 Self {
564 header: builder.header_protection_key(),
565 packet: builder.packet_key(),
566 }
567 }
568}
569
570const TAG_LEN: usize = 16;
572
573pub struct Tag([u8; TAG_LEN]);
575
576impl From<&[u8]> for Tag {
577 fn from(value: &[u8]) -> Self {
578 let mut array = [0u8; TAG_LEN];
579 array.copy_from_slice(value);
580 Self(array)
581 }
582}
583
584impl AsRef<[u8]> for Tag {
585 fn as_ref(&self) -> &[u8] {
586 &self.0
587 }
588}
589
590pub trait Algorithm: Send + Sync {
592 fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn PacketKey>;
597
598 fn header_protection_key(&self, key: AeadKey) -> Box<dyn HeaderProtectionKey>;
602
603 fn aead_key_len(&self) -> usize;
607
608 fn fips(&self) -> bool {
610 false
611 }
612}
613
614pub trait HeaderProtectionKey: Send + Sync {
616 fn encrypt_in_place(
637 &self,
638 sample: &[u8],
639 first: &mut u8,
640 packet_number: &mut [u8],
641 ) -> Result<(), Error>;
642
643 fn decrypt_in_place(
665 &self,
666 sample: &[u8],
667 first: &mut u8,
668 packet_number: &mut [u8],
669 ) -> Result<(), Error>;
670
671 fn sample_len(&self) -> usize;
673}
674
675pub trait PacketKey: Send + Sync {
677 fn encrypt_in_place(
685 &self,
686 packet_number: u64,
687 header: &[u8],
688 payload: &mut [u8],
689 ) -> Result<Tag, Error>;
690
691 fn decrypt_in_place<'a>(
699 &self,
700 packet_number: u64,
701 header: &[u8],
702 payload: &'a mut [u8],
703 ) -> Result<&'a [u8], Error>;
704
705 fn tag_len(&self) -> usize;
707
708 fn confidentiality_limit(&self) -> u64;
719
720 fn integrity_limit(&self) -> u64;
729}
730
731pub struct PacketKeySet {
733 pub local: Box<dyn PacketKey>,
735 pub remote: Box<dyn PacketKey>,
737}
738
739impl PacketKeySet {
740 fn new(secrets: &Secrets) -> Self {
741 let (local, remote) = secrets.local_remote();
742 let (version, alg, hkdf) = (secrets.version, secrets.quic, secrets.suite.hkdf_provider);
743 Self {
744 local: KeyBuilder::new(local, version, alg, hkdf).packet_key(),
745 remote: KeyBuilder::new(remote, version, alg, hkdf).packet_key(),
746 }
747 }
748}
749
750pub(crate) struct KeyBuilder<'a> {
751 expander: Box<dyn HkdfExpander>,
752 version: Version,
753 alg: &'a dyn Algorithm,
754}
755
756impl<'a> KeyBuilder<'a> {
757 pub(crate) fn new(
758 secret: &OkmBlock,
759 version: Version,
760 alg: &'a dyn Algorithm,
761 hkdf: &'a dyn Hkdf,
762 ) -> Self {
763 Self {
764 expander: hkdf.expander_for_okm(secret),
765 version,
766 alg,
767 }
768 }
769
770 pub(crate) fn packet_key(&self) -> Box<dyn PacketKey> {
772 let aead_key_len = self.alg.aead_key_len();
773 let packet_key = hkdf_expand_label_aead_key(
774 self.expander.as_ref(),
775 aead_key_len,
776 self.version.packet_key_label(),
777 &[],
778 );
779
780 let packet_iv =
781 hkdf_expand_label(self.expander.as_ref(), self.version.packet_iv_label(), &[]);
782 self.alg
783 .packet_key(packet_key, packet_iv)
784 }
785
786 pub(crate) fn header_protection_key(&self) -> Box<dyn HeaderProtectionKey> {
788 let header_key = hkdf_expand_label_aead_key(
789 self.expander.as_ref(),
790 self.alg.aead_key_len(),
791 self.version.header_key_label(),
792 &[],
793 );
794 self.alg
795 .header_protection_key(header_key)
796 }
797}
798
799pub struct Suite {
801 pub suite: &'static Tls13CipherSuite,
803 pub quic: &'static dyn Algorithm,
805}
806
807impl Suite {
808 pub fn keys(&self, client_dst_connection_id: &[u8], side: Side, version: Version) -> Keys {
810 Keys::initial(
811 version,
812 self.suite,
813 self.quic,
814 client_dst_connection_id,
815 side,
816 )
817 }
818}
819
820pub struct Keys {
822 pub local: DirectionalKeys,
824 pub remote: DirectionalKeys,
826}
827
828impl Keys {
829 pub fn initial(
831 version: Version,
832 suite: &'static Tls13CipherSuite,
833 quic: &'static dyn Algorithm,
834 client_dst_connection_id: &[u8],
835 side: Side,
836 ) -> Self {
837 const CLIENT_LABEL: &[u8] = b"client in";
838 const SERVER_LABEL: &[u8] = b"server in";
839 let salt = version.initial_salt();
840 let hs_secret = suite
841 .hkdf_provider
842 .extract_from_secret(Some(salt), client_dst_connection_id);
843
844 let secrets = Secrets {
845 version,
846 client: hkdf_expand_label_block(hs_secret.as_ref(), CLIENT_LABEL, &[]),
847 server: hkdf_expand_label_block(hs_secret.as_ref(), SERVER_LABEL, &[]),
848 suite,
849 quic,
850 side,
851 };
852 Self::new(&secrets)
853 }
854
855 fn new(secrets: &Secrets) -> Self {
856 let (local, remote) = secrets.local_remote();
857 Self {
858 local: DirectionalKeys::new(secrets.suite, secrets.quic, local, secrets.version),
859 remote: DirectionalKeys::new(secrets.suite, secrets.quic, remote, secrets.version),
860 }
861 }
862}
863
864#[allow(clippy::large_enum_variant)]
878pub enum KeyChange {
879 Handshake {
881 keys: Keys,
883 },
884 OneRtt {
886 keys: Keys,
888 next: Secrets,
890 },
891}
892
893#[non_exhaustive]
897#[derive(Clone, Copy, Debug)]
898pub enum Version {
899 V1Draft,
901 V1,
903 V2,
905}
906
907impl Version {
908 fn initial_salt(self) -> &'static [u8; 20] {
909 match self {
910 Self::V1Draft => &[
911 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
913 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
914 ],
915 Self::V1 => &[
916 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
918 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
919 ],
920 Self::V2 => &[
921 0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26,
923 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9,
924 ],
925 }
926 }
927
928 pub(crate) fn packet_key_label(&self) -> &'static [u8] {
930 match self {
931 Self::V1Draft | Self::V1 => b"quic key",
932 Self::V2 => b"quicv2 key",
933 }
934 }
935
936 pub(crate) fn packet_iv_label(&self) -> &'static [u8] {
938 match self {
939 Self::V1Draft | Self::V1 => b"quic iv",
940 Self::V2 => b"quicv2 iv",
941 }
942 }
943
944 pub(crate) fn header_key_label(&self) -> &'static [u8] {
946 match self {
947 Self::V1Draft | Self::V1 => b"quic hp",
948 Self::V2 => b"quicv2 hp",
949 }
950 }
951
952 fn key_update_label(&self) -> &'static [u8] {
953 match self {
954 Self::V1Draft | Self::V1 => b"quic ku",
955 Self::V2 => b"quicv2 ku",
956 }
957 }
958}
959
960impl Default for Version {
961 fn default() -> Self {
962 Self::V1
963 }
964}
965
966#[cfg(test)]
967mod tests {
968 use std::prelude::v1::*;
969
970 use super::PacketKey;
971 use crate::quic::HeaderProtectionKey;
972
973 #[test]
974 fn auto_traits() {
975 fn assert_auto<T: Send + Sync>() {}
976 assert_auto::<Box<dyn PacketKey>>();
977 assert_auto::<Box<dyn HeaderProtectionKey>>();
978 }
979}