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, ContentType, ProtocolVersion};
33 use crate::error::Error;
34 use crate::msgs::deframer::buffers::{DeframerVecBuffer, Locator};
35 use crate::msgs::handshake::{ClientExtension, ServerExtension};
36 use crate::msgs::message::InboundPlainMessage;
37 use crate::server::{ServerConfig, ServerConnectionData};
38 use crate::vecbuf::ChunkVecBuffer;
39
40 #[derive(Debug)]
42 pub enum Connection {
43 Client(ClientConnection),
45 Server(ServerConnection),
47 }
48
49 impl Connection {
50 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
54 match self {
55 Self::Client(conn) => conn.quic_transport_parameters(),
56 Self::Server(conn) => conn.quic_transport_parameters(),
57 }
58 }
59
60 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
62 match self {
63 Self::Client(conn) => conn.zero_rtt_keys(),
64 Self::Server(conn) => conn.zero_rtt_keys(),
65 }
66 }
67
68 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
72 match self {
73 Self::Client(conn) => conn.read_hs(plaintext),
74 Self::Server(conn) => conn.read_hs(plaintext),
75 }
76 }
77
78 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
82 match self {
83 Self::Client(conn) => conn.write_hs(buf),
84 Self::Server(conn) => conn.write_hs(buf),
85 }
86 }
87
88 pub fn alert(&self) -> Option<AlertDescription> {
92 match self {
93 Self::Client(conn) => conn.alert(),
94 Self::Server(conn) => conn.alert(),
95 }
96 }
97
98 #[inline]
114 pub fn export_keying_material<T: AsMut<[u8]>>(
115 &self,
116 output: T,
117 label: &[u8],
118 context: Option<&[u8]>,
119 ) -> Result<T, Error> {
120 match self {
121 Self::Client(conn) => conn
122 .core
123 .export_keying_material(output, label, context),
124 Self::Server(conn) => conn
125 .core
126 .export_keying_material(output, label, context),
127 }
128 }
129 }
130
131 impl Deref for Connection {
132 type Target = CommonState;
133
134 fn deref(&self) -> &Self::Target {
135 match self {
136 Self::Client(conn) => &conn.core.common_state,
137 Self::Server(conn) => &conn.core.common_state,
138 }
139 }
140 }
141
142 impl DerefMut for Connection {
143 fn deref_mut(&mut self) -> &mut Self::Target {
144 match self {
145 Self::Client(conn) => &mut conn.core.common_state,
146 Self::Server(conn) => &mut conn.core.common_state,
147 }
148 }
149 }
150
151 pub struct ClientConnection {
153 inner: ConnectionCommon<ClientConnectionData>,
154 }
155
156 impl ClientConnection {
157 pub fn new(
162 config: Arc<ClientConfig>,
163 quic_version: Version,
164 name: ServerName<'static>,
165 params: Vec<u8>,
166 ) -> Result<Self, Error> {
167 if !config.supports_version(ProtocolVersion::TLSv1_3) {
168 return Err(Error::General(
169 "TLS 1.3 support is required for QUIC".into(),
170 ));
171 }
172
173 if !config.supports_protocol(Protocol::Quic) {
174 return Err(Error::General(
175 "at least one ciphersuite must support QUIC".into(),
176 ));
177 }
178
179 let ext = match quic_version {
180 Version::V1Draft => ClientExtension::TransportParametersDraft(params),
181 Version::V1 | Version::V2 => ClientExtension::TransportParameters(params),
182 };
183
184 let mut inner = ConnectionCore::for_client(config, name, vec![ext], Protocol::Quic)?;
185 inner.common_state.quic.version = quic_version;
186 Ok(Self {
187 inner: inner.into(),
188 })
189 }
190
191 pub fn is_early_data_accepted(&self) -> bool {
197 self.inner.core.is_early_data_accepted()
198 }
199 }
200
201 impl Deref for ClientConnection {
202 type Target = ConnectionCommon<ClientConnectionData>;
203
204 fn deref(&self) -> &Self::Target {
205 &self.inner
206 }
207 }
208
209 impl DerefMut for ClientConnection {
210 fn deref_mut(&mut self) -> &mut Self::Target {
211 &mut self.inner
212 }
213 }
214
215 impl Debug for ClientConnection {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 f.debug_struct("quic::ClientConnection")
218 .finish()
219 }
220 }
221
222 impl From<ClientConnection> for Connection {
223 fn from(c: ClientConnection) -> Self {
224 Self::Client(c)
225 }
226 }
227
228 pub struct ServerConnection {
230 inner: ConnectionCommon<ServerConnectionData>,
231 }
232
233 impl ServerConnection {
234 pub fn new(
239 config: Arc<ServerConfig>,
240 quic_version: Version,
241 params: Vec<u8>,
242 ) -> Result<Self, Error> {
243 if !config.supports_version(ProtocolVersion::TLSv1_3) {
244 return Err(Error::General(
245 "TLS 1.3 support is required for QUIC".into(),
246 ));
247 }
248
249 if !config.supports_protocol(Protocol::Quic) {
250 return Err(Error::General(
251 "at least one ciphersuite must support QUIC".into(),
252 ));
253 }
254
255 if config.max_early_data_size != 0 && config.max_early_data_size != 0xffff_ffff {
256 return Err(Error::General(
257 "QUIC sessions must set a max early data of 0 or 2^32-1".into(),
258 ));
259 }
260
261 let ext = match quic_version {
262 Version::V1Draft => ServerExtension::TransportParametersDraft(params),
263 Version::V1 | Version::V2 => ServerExtension::TransportParameters(params),
264 };
265
266 let mut core = ConnectionCore::for_server(config, vec![ext])?;
267 core.common_state.protocol = Protocol::Quic;
268 core.common_state.quic.version = quic_version;
269 Ok(Self { inner: core.into() })
270 }
271
272 pub fn reject_early_data(&mut self) {
278 self.inner.core.reject_early_data()
279 }
280
281 pub fn server_name(&self) -> Option<&str> {
297 self.inner.core.get_sni_str()
298 }
299 }
300
301 impl Deref for ServerConnection {
302 type Target = ConnectionCommon<ServerConnectionData>;
303
304 fn deref(&self) -> &Self::Target {
305 &self.inner
306 }
307 }
308
309 impl DerefMut for ServerConnection {
310 fn deref_mut(&mut self) -> &mut Self::Target {
311 &mut self.inner
312 }
313 }
314
315 impl Debug for ServerConnection {
316 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317 f.debug_struct("quic::ServerConnection")
318 .finish()
319 }
320 }
321
322 impl From<ServerConnection> for Connection {
323 fn from(c: ServerConnection) -> Self {
324 Self::Server(c)
325 }
326 }
327
328 pub struct ConnectionCommon<Data> {
330 core: ConnectionCore<Data>,
331 deframer_buffer: DeframerVecBuffer,
332 sendable_plaintext: ChunkVecBuffer,
333 }
334
335 impl<Data: SideData> ConnectionCommon<Data> {
336 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
344 self.core
345 .common_state
346 .quic
347 .params
348 .as_ref()
349 .map(|v| v.as_ref())
350 }
351
352 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
354 let suite = self
355 .core
356 .common_state
357 .suite
358 .and_then(|suite| suite.tls13())?;
359 Some(DirectionalKeys::new(
360 suite,
361 suite.quic?,
362 self.core
363 .common_state
364 .quic
365 .early_secret
366 .as_ref()?,
367 self.core.common_state.quic.version,
368 ))
369 }
370
371 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
375 let range = self.deframer_buffer.extend(plaintext);
376
377 self.core.hs_deframer.input_message(
378 InboundPlainMessage {
379 typ: ContentType::Handshake,
380 version: ProtocolVersion::TLSv1_3,
381 payload: &self.deframer_buffer.filled()[range.clone()],
382 },
383 &Locator::new(self.deframer_buffer.filled()),
384 range.end,
385 );
386
387 self.deframer_buffer.processed = range.end;
390
391 self.core
392 .hs_deframer
393 .coalesce(self.deframer_buffer.filled_mut())?;
394
395 self.core
396 .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)?;
397
398 Ok(())
399 }
400
401 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
405 self.core
406 .common_state
407 .quic
408 .write_hs(buf)
409 }
410
411 pub fn alert(&self) -> Option<AlertDescription> {
415 self.core.common_state.quic.alert
416 }
417 }
418
419 impl<Data> Deref for ConnectionCommon<Data> {
420 type Target = CommonState;
421
422 fn deref(&self) -> &Self::Target {
423 &self.core.common_state
424 }
425 }
426
427 impl<Data> DerefMut for ConnectionCommon<Data> {
428 fn deref_mut(&mut self) -> &mut Self::Target {
429 &mut self.core.common_state
430 }
431 }
432
433 impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
434 fn from(core: ConnectionCore<Data>) -> Self {
435 Self {
436 core,
437 deframer_buffer: DeframerVecBuffer::default(),
438 sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
439 }
440 }
441 }
442}
443
444#[cfg(feature = "std")]
445pub use connection::{ClientConnection, Connection, ConnectionCommon, ServerConnection};
446
447#[derive(Default)]
448pub(crate) struct Quic {
449 pub(crate) params: Option<Vec<u8>>,
451 pub(crate) alert: Option<AlertDescription>,
452 pub(crate) hs_queue: VecDeque<(bool, Vec<u8>)>,
453 pub(crate) early_secret: Option<OkmBlock>,
454 pub(crate) hs_secrets: Option<Secrets>,
455 pub(crate) traffic_secrets: Option<Secrets>,
456 #[cfg(feature = "std")]
458 pub(crate) returned_traffic_keys: bool,
459 pub(crate) version: Version,
460}
461
462#[cfg(feature = "std")]
463impl Quic {
464 pub(crate) fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
465 while let Some((_, msg)) = self.hs_queue.pop_front() {
466 buf.extend_from_slice(&msg);
467 if let Some(&(true, _)) = self.hs_queue.front() {
468 if self.hs_secrets.is_some() {
469 break;
471 }
472 }
473 }
474
475 if let Some(secrets) = self.hs_secrets.take() {
476 return Some(KeyChange::Handshake {
477 keys: Keys::new(&secrets),
478 });
479 }
480
481 if let Some(mut secrets) = self.traffic_secrets.take() {
482 if !self.returned_traffic_keys {
483 self.returned_traffic_keys = true;
484 let keys = Keys::new(&secrets);
485 secrets.update();
486 return Some(KeyChange::OneRtt {
487 keys,
488 next: secrets,
489 });
490 }
491 }
492
493 None
494 }
495}
496
497#[derive(Clone)]
499pub struct Secrets {
500 pub(crate) client: OkmBlock,
502 pub(crate) server: OkmBlock,
504 suite: &'static Tls13CipherSuite,
506 quic: &'static dyn Algorithm,
507 side: Side,
508 version: Version,
509}
510
511impl Secrets {
512 pub(crate) fn new(
513 client: OkmBlock,
514 server: OkmBlock,
515 suite: &'static Tls13CipherSuite,
516 quic: &'static dyn Algorithm,
517 side: Side,
518 version: Version,
519 ) -> Self {
520 Self {
521 client,
522 server,
523 suite,
524 quic,
525 side,
526 version,
527 }
528 }
529
530 pub fn next_packet_keys(&mut self) -> PacketKeySet {
532 let keys = PacketKeySet::new(self);
533 self.update();
534 keys
535 }
536
537 pub(crate) fn update(&mut self) {
538 self.client = hkdf_expand_label_block(
539 self.suite
540 .hkdf_provider
541 .expander_for_okm(&self.client)
542 .as_ref(),
543 self.version.key_update_label(),
544 &[],
545 );
546 self.server = hkdf_expand_label_block(
547 self.suite
548 .hkdf_provider
549 .expander_for_okm(&self.server)
550 .as_ref(),
551 self.version.key_update_label(),
552 &[],
553 );
554 }
555
556 fn local_remote(&self) -> (&OkmBlock, &OkmBlock) {
557 match self.side {
558 Side::Client => (&self.client, &self.server),
559 Side::Server => (&self.server, &self.client),
560 }
561 }
562}
563
564pub struct DirectionalKeys {
566 pub header: Box<dyn HeaderProtectionKey>,
568 pub packet: Box<dyn PacketKey>,
570}
571
572impl DirectionalKeys {
573 pub(crate) fn new(
574 suite: &'static Tls13CipherSuite,
575 quic: &'static dyn Algorithm,
576 secret: &OkmBlock,
577 version: Version,
578 ) -> Self {
579 let builder = KeyBuilder::new(secret, version, quic, suite.hkdf_provider);
580 Self {
581 header: builder.header_protection_key(),
582 packet: builder.packet_key(),
583 }
584 }
585}
586
587const TAG_LEN: usize = 16;
589
590pub struct Tag([u8; TAG_LEN]);
592
593impl From<&[u8]> for Tag {
594 fn from(value: &[u8]) -> Self {
595 let mut array = [0u8; TAG_LEN];
596 array.copy_from_slice(value);
597 Self(array)
598 }
599}
600
601impl AsRef<[u8]> for Tag {
602 fn as_ref(&self) -> &[u8] {
603 &self.0
604 }
605}
606
607pub trait Algorithm: Send + Sync {
609 fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn PacketKey>;
614
615 fn header_protection_key(&self, key: AeadKey) -> Box<dyn HeaderProtectionKey>;
619
620 fn aead_key_len(&self) -> usize;
624
625 fn fips(&self) -> bool {
627 false
628 }
629}
630
631pub trait HeaderProtectionKey: Send + Sync {
633 fn encrypt_in_place(
654 &self,
655 sample: &[u8],
656 first: &mut u8,
657 packet_number: &mut [u8],
658 ) -> Result<(), Error>;
659
660 fn decrypt_in_place(
682 &self,
683 sample: &[u8],
684 first: &mut u8,
685 packet_number: &mut [u8],
686 ) -> Result<(), Error>;
687
688 fn sample_len(&self) -> usize;
690}
691
692pub trait PacketKey: Send + Sync {
694 fn encrypt_in_place(
702 &self,
703 packet_number: u64,
704 header: &[u8],
705 payload: &mut [u8],
706 ) -> Result<Tag, Error>;
707
708 fn decrypt_in_place<'a>(
716 &self,
717 packet_number: u64,
718 header: &[u8],
719 payload: &'a mut [u8],
720 ) -> Result<&'a [u8], Error>;
721
722 fn tag_len(&self) -> usize;
724
725 fn confidentiality_limit(&self) -> u64;
736
737 fn integrity_limit(&self) -> u64;
746}
747
748pub struct PacketKeySet {
750 pub local: Box<dyn PacketKey>,
752 pub remote: Box<dyn PacketKey>,
754}
755
756impl PacketKeySet {
757 fn new(secrets: &Secrets) -> Self {
758 let (local, remote) = secrets.local_remote();
759 let (version, alg, hkdf) = (secrets.version, secrets.quic, secrets.suite.hkdf_provider);
760 Self {
761 local: KeyBuilder::new(local, version, alg, hkdf).packet_key(),
762 remote: KeyBuilder::new(remote, version, alg, hkdf).packet_key(),
763 }
764 }
765}
766
767pub(crate) struct KeyBuilder<'a> {
768 expander: Box<dyn HkdfExpander>,
769 version: Version,
770 alg: &'a dyn Algorithm,
771}
772
773impl<'a> KeyBuilder<'a> {
774 pub(crate) fn new(
775 secret: &OkmBlock,
776 version: Version,
777 alg: &'a dyn Algorithm,
778 hkdf: &'a dyn Hkdf,
779 ) -> Self {
780 Self {
781 expander: hkdf.expander_for_okm(secret),
782 version,
783 alg,
784 }
785 }
786
787 pub(crate) fn packet_key(&self) -> Box<dyn PacketKey> {
789 let aead_key_len = self.alg.aead_key_len();
790 let packet_key = hkdf_expand_label_aead_key(
791 self.expander.as_ref(),
792 aead_key_len,
793 self.version.packet_key_label(),
794 &[],
795 );
796
797 let packet_iv =
798 hkdf_expand_label(self.expander.as_ref(), self.version.packet_iv_label(), &[]);
799 self.alg
800 .packet_key(packet_key, packet_iv)
801 }
802
803 pub(crate) fn header_protection_key(&self) -> Box<dyn HeaderProtectionKey> {
805 let header_key = hkdf_expand_label_aead_key(
806 self.expander.as_ref(),
807 self.alg.aead_key_len(),
808 self.version.header_key_label(),
809 &[],
810 );
811 self.alg
812 .header_protection_key(header_key)
813 }
814}
815
816#[derive(Clone, Copy)]
818pub struct Suite {
819 pub suite: &'static Tls13CipherSuite,
821 pub quic: &'static dyn Algorithm,
823}
824
825impl Suite {
826 pub fn keys(&self, client_dst_connection_id: &[u8], side: Side, version: Version) -> Keys {
828 Keys::initial(
829 version,
830 self.suite,
831 self.quic,
832 client_dst_connection_id,
833 side,
834 )
835 }
836}
837
838pub struct Keys {
840 pub local: DirectionalKeys,
842 pub remote: DirectionalKeys,
844}
845
846impl Keys {
847 pub fn initial(
849 version: Version,
850 suite: &'static Tls13CipherSuite,
851 quic: &'static dyn Algorithm,
852 client_dst_connection_id: &[u8],
853 side: Side,
854 ) -> Self {
855 const CLIENT_LABEL: &[u8] = b"client in";
856 const SERVER_LABEL: &[u8] = b"server in";
857 let salt = version.initial_salt();
858 let hs_secret = suite
859 .hkdf_provider
860 .extract_from_secret(Some(salt), client_dst_connection_id);
861
862 let secrets = Secrets {
863 version,
864 client: hkdf_expand_label_block(hs_secret.as_ref(), CLIENT_LABEL, &[]),
865 server: hkdf_expand_label_block(hs_secret.as_ref(), SERVER_LABEL, &[]),
866 suite,
867 quic,
868 side,
869 };
870 Self::new(&secrets)
871 }
872
873 fn new(secrets: &Secrets) -> Self {
874 let (local, remote) = secrets.local_remote();
875 Self {
876 local: DirectionalKeys::new(secrets.suite, secrets.quic, local, secrets.version),
877 remote: DirectionalKeys::new(secrets.suite, secrets.quic, remote, secrets.version),
878 }
879 }
880}
881
882pub enum KeyChange {
896 Handshake {
898 keys: Keys,
900 },
901 OneRtt {
903 keys: Keys,
905 next: Secrets,
907 },
908}
909
910#[non_exhaustive]
914#[derive(Clone, Copy, Debug)]
915pub enum Version {
916 V1Draft,
918 V1,
920 V2,
922}
923
924impl Version {
925 fn initial_salt(self) -> &'static [u8; 20] {
926 match self {
927 Self::V1Draft => &[
928 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
930 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
931 ],
932 Self::V1 => &[
933 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
935 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
936 ],
937 Self::V2 => &[
938 0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26,
940 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9,
941 ],
942 }
943 }
944
945 pub(crate) fn packet_key_label(&self) -> &'static [u8] {
947 match self {
948 Self::V1Draft | Self::V1 => b"quic key",
949 Self::V2 => b"quicv2 key",
950 }
951 }
952
953 pub(crate) fn packet_iv_label(&self) -> &'static [u8] {
955 match self {
956 Self::V1Draft | Self::V1 => b"quic iv",
957 Self::V2 => b"quicv2 iv",
958 }
959 }
960
961 pub(crate) fn header_key_label(&self) -> &'static [u8] {
963 match self {
964 Self::V1Draft | Self::V1 => b"quic hp",
965 Self::V2 => b"quicv2 hp",
966 }
967 }
968
969 fn key_update_label(&self) -> &'static [u8] {
970 match self {
971 Self::V1Draft | Self::V1 => b"quic ku",
972 Self::V2 => b"quicv2 ku",
973 }
974 }
975}
976
977impl Default for Version {
978 fn default() -> Self {
979 Self::V1
980 }
981}
982
983#[cfg(test)]
984mod tests {
985 use std::prelude::v1::*;
986
987 use super::PacketKey;
988 use crate::quic::HeaderProtectionKey;
989
990 #[test]
991 fn auto_traits() {
992 fn assert_auto<T: Send + Sync>() {}
993 assert_auto::<Box<dyn PacketKey>>();
994 assert_auto::<Box<dyn HeaderProtectionKey>>();
995 }
996}