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.core
388 .hs_deframer
389 .coalesce(self.deframer_buffer.filled_mut())?;
390
391 self.core
392 .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)?;
393
394 Ok(())
395 }
396
397 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
401 self.core
402 .common_state
403 .quic
404 .write_hs(buf)
405 }
406
407 pub fn alert(&self) -> Option<AlertDescription> {
411 self.core.common_state.quic.alert
412 }
413 }
414
415 impl<Data> Deref for ConnectionCommon<Data> {
416 type Target = CommonState;
417
418 fn deref(&self) -> &Self::Target {
419 &self.core.common_state
420 }
421 }
422
423 impl<Data> DerefMut for ConnectionCommon<Data> {
424 fn deref_mut(&mut self) -> &mut Self::Target {
425 &mut self.core.common_state
426 }
427 }
428
429 impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
430 fn from(core: ConnectionCore<Data>) -> Self {
431 Self {
432 core,
433 deframer_buffer: DeframerVecBuffer::default(),
434 sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
435 }
436 }
437 }
438}
439
440#[cfg(feature = "std")]
441pub use connection::{ClientConnection, Connection, ConnectionCommon, ServerConnection};
442
443#[derive(Default)]
444pub(crate) struct Quic {
445 pub(crate) params: Option<Vec<u8>>,
447 pub(crate) alert: Option<AlertDescription>,
448 pub(crate) hs_queue: VecDeque<(bool, Vec<u8>)>,
449 pub(crate) early_secret: Option<OkmBlock>,
450 pub(crate) hs_secrets: Option<Secrets>,
451 pub(crate) traffic_secrets: Option<Secrets>,
452 #[cfg(feature = "std")]
454 pub(crate) returned_traffic_keys: bool,
455 pub(crate) version: Version,
456}
457
458#[cfg(feature = "std")]
459impl Quic {
460 pub(crate) fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
461 while let Some((_, msg)) = self.hs_queue.pop_front() {
462 buf.extend_from_slice(&msg);
463 if let Some(&(true, _)) = self.hs_queue.front() {
464 if self.hs_secrets.is_some() {
465 break;
467 }
468 }
469 }
470
471 if let Some(secrets) = self.hs_secrets.take() {
472 return Some(KeyChange::Handshake {
473 keys: Keys::new(&secrets),
474 });
475 }
476
477 if let Some(mut secrets) = self.traffic_secrets.take() {
478 if !self.returned_traffic_keys {
479 self.returned_traffic_keys = true;
480 let keys = Keys::new(&secrets);
481 secrets.update();
482 return Some(KeyChange::OneRtt {
483 keys,
484 next: secrets,
485 });
486 }
487 }
488
489 None
490 }
491}
492
493#[derive(Clone)]
495pub struct Secrets {
496 pub(crate) client: OkmBlock,
498 pub(crate) server: OkmBlock,
500 suite: &'static Tls13CipherSuite,
502 quic: &'static dyn Algorithm,
503 side: Side,
504 version: Version,
505}
506
507impl Secrets {
508 pub(crate) fn new(
509 client: OkmBlock,
510 server: OkmBlock,
511 suite: &'static Tls13CipherSuite,
512 quic: &'static dyn Algorithm,
513 side: Side,
514 version: Version,
515 ) -> Self {
516 Self {
517 client,
518 server,
519 suite,
520 quic,
521 side,
522 version,
523 }
524 }
525
526 pub fn next_packet_keys(&mut self) -> PacketKeySet {
528 let keys = PacketKeySet::new(self);
529 self.update();
530 keys
531 }
532
533 pub(crate) fn update(&mut self) {
534 self.client = hkdf_expand_label_block(
535 self.suite
536 .hkdf_provider
537 .expander_for_okm(&self.client)
538 .as_ref(),
539 self.version.key_update_label(),
540 &[],
541 );
542 self.server = hkdf_expand_label_block(
543 self.suite
544 .hkdf_provider
545 .expander_for_okm(&self.server)
546 .as_ref(),
547 self.version.key_update_label(),
548 &[],
549 );
550 }
551
552 fn local_remote(&self) -> (&OkmBlock, &OkmBlock) {
553 match self.side {
554 Side::Client => (&self.client, &self.server),
555 Side::Server => (&self.server, &self.client),
556 }
557 }
558}
559
560pub struct DirectionalKeys {
562 pub header: Box<dyn HeaderProtectionKey>,
564 pub packet: Box<dyn PacketKey>,
566}
567
568impl DirectionalKeys {
569 pub(crate) fn new(
570 suite: &'static Tls13CipherSuite,
571 quic: &'static dyn Algorithm,
572 secret: &OkmBlock,
573 version: Version,
574 ) -> Self {
575 let builder = KeyBuilder::new(secret, version, quic, suite.hkdf_provider);
576 Self {
577 header: builder.header_protection_key(),
578 packet: builder.packet_key(),
579 }
580 }
581}
582
583const TAG_LEN: usize = 16;
585
586pub struct Tag([u8; TAG_LEN]);
588
589impl From<&[u8]> for Tag {
590 fn from(value: &[u8]) -> Self {
591 let mut array = [0u8; TAG_LEN];
592 array.copy_from_slice(value);
593 Self(array)
594 }
595}
596
597impl AsRef<[u8]> for Tag {
598 fn as_ref(&self) -> &[u8] {
599 &self.0
600 }
601}
602
603pub trait Algorithm: Send + Sync {
605 fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn PacketKey>;
610
611 fn header_protection_key(&self, key: AeadKey) -> Box<dyn HeaderProtectionKey>;
615
616 fn aead_key_len(&self) -> usize;
620
621 fn fips(&self) -> bool {
623 false
624 }
625}
626
627pub trait HeaderProtectionKey: Send + Sync {
629 fn encrypt_in_place(
650 &self,
651 sample: &[u8],
652 first: &mut u8,
653 packet_number: &mut [u8],
654 ) -> Result<(), Error>;
655
656 fn decrypt_in_place(
678 &self,
679 sample: &[u8],
680 first: &mut u8,
681 packet_number: &mut [u8],
682 ) -> Result<(), Error>;
683
684 fn sample_len(&self) -> usize;
686}
687
688pub trait PacketKey: Send + Sync {
690 fn encrypt_in_place(
698 &self,
699 packet_number: u64,
700 header: &[u8],
701 payload: &mut [u8],
702 ) -> Result<Tag, Error>;
703
704 fn decrypt_in_place<'a>(
712 &self,
713 packet_number: u64,
714 header: &[u8],
715 payload: &'a mut [u8],
716 ) -> Result<&'a [u8], Error>;
717
718 fn tag_len(&self) -> usize;
720
721 fn confidentiality_limit(&self) -> u64;
732
733 fn integrity_limit(&self) -> u64;
742}
743
744pub struct PacketKeySet {
746 pub local: Box<dyn PacketKey>,
748 pub remote: Box<dyn PacketKey>,
750}
751
752impl PacketKeySet {
753 fn new(secrets: &Secrets) -> Self {
754 let (local, remote) = secrets.local_remote();
755 let (version, alg, hkdf) = (secrets.version, secrets.quic, secrets.suite.hkdf_provider);
756 Self {
757 local: KeyBuilder::new(local, version, alg, hkdf).packet_key(),
758 remote: KeyBuilder::new(remote, version, alg, hkdf).packet_key(),
759 }
760 }
761}
762
763pub(crate) struct KeyBuilder<'a> {
764 expander: Box<dyn HkdfExpander>,
765 version: Version,
766 alg: &'a dyn Algorithm,
767}
768
769impl<'a> KeyBuilder<'a> {
770 pub(crate) fn new(
771 secret: &OkmBlock,
772 version: Version,
773 alg: &'a dyn Algorithm,
774 hkdf: &'a dyn Hkdf,
775 ) -> Self {
776 Self {
777 expander: hkdf.expander_for_okm(secret),
778 version,
779 alg,
780 }
781 }
782
783 pub(crate) fn packet_key(&self) -> Box<dyn PacketKey> {
785 let aead_key_len = self.alg.aead_key_len();
786 let packet_key = hkdf_expand_label_aead_key(
787 self.expander.as_ref(),
788 aead_key_len,
789 self.version.packet_key_label(),
790 &[],
791 );
792
793 let packet_iv =
794 hkdf_expand_label(self.expander.as_ref(), self.version.packet_iv_label(), &[]);
795 self.alg
796 .packet_key(packet_key, packet_iv)
797 }
798
799 pub(crate) fn header_protection_key(&self) -> Box<dyn HeaderProtectionKey> {
801 let header_key = hkdf_expand_label_aead_key(
802 self.expander.as_ref(),
803 self.alg.aead_key_len(),
804 self.version.header_key_label(),
805 &[],
806 );
807 self.alg
808 .header_protection_key(header_key)
809 }
810}
811
812#[derive(Clone, Copy)]
814pub struct Suite {
815 pub suite: &'static Tls13CipherSuite,
817 pub quic: &'static dyn Algorithm,
819}
820
821impl Suite {
822 pub fn keys(&self, client_dst_connection_id: &[u8], side: Side, version: Version) -> Keys {
824 Keys::initial(
825 version,
826 self.suite,
827 self.quic,
828 client_dst_connection_id,
829 side,
830 )
831 }
832}
833
834pub struct Keys {
836 pub local: DirectionalKeys,
838 pub remote: DirectionalKeys,
840}
841
842impl Keys {
843 pub fn initial(
845 version: Version,
846 suite: &'static Tls13CipherSuite,
847 quic: &'static dyn Algorithm,
848 client_dst_connection_id: &[u8],
849 side: Side,
850 ) -> Self {
851 const CLIENT_LABEL: &[u8] = b"client in";
852 const SERVER_LABEL: &[u8] = b"server in";
853 let salt = version.initial_salt();
854 let hs_secret = suite
855 .hkdf_provider
856 .extract_from_secret(Some(salt), client_dst_connection_id);
857
858 let secrets = Secrets {
859 version,
860 client: hkdf_expand_label_block(hs_secret.as_ref(), CLIENT_LABEL, &[]),
861 server: hkdf_expand_label_block(hs_secret.as_ref(), SERVER_LABEL, &[]),
862 suite,
863 quic,
864 side,
865 };
866 Self::new(&secrets)
867 }
868
869 fn new(secrets: &Secrets) -> Self {
870 let (local, remote) = secrets.local_remote();
871 Self {
872 local: DirectionalKeys::new(secrets.suite, secrets.quic, local, secrets.version),
873 remote: DirectionalKeys::new(secrets.suite, secrets.quic, remote, secrets.version),
874 }
875 }
876}
877
878pub enum KeyChange {
892 Handshake {
894 keys: Keys,
896 },
897 OneRtt {
899 keys: Keys,
901 next: Secrets,
903 },
904}
905
906#[non_exhaustive]
910#[derive(Clone, Copy, Debug)]
911pub enum Version {
912 V1Draft,
914 V1,
916 V2,
918}
919
920impl Version {
921 fn initial_salt(self) -> &'static [u8; 20] {
922 match self {
923 Self::V1Draft => &[
924 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
926 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
927 ],
928 Self::V1 => &[
929 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
931 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
932 ],
933 Self::V2 => &[
934 0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26,
936 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9,
937 ],
938 }
939 }
940
941 pub(crate) fn packet_key_label(&self) -> &'static [u8] {
943 match self {
944 Self::V1Draft | Self::V1 => b"quic key",
945 Self::V2 => b"quicv2 key",
946 }
947 }
948
949 pub(crate) fn packet_iv_label(&self) -> &'static [u8] {
951 match self {
952 Self::V1Draft | Self::V1 => b"quic iv",
953 Self::V2 => b"quicv2 iv",
954 }
955 }
956
957 pub(crate) fn header_key_label(&self) -> &'static [u8] {
959 match self {
960 Self::V1Draft | Self::V1 => b"quic hp",
961 Self::V2 => b"quicv2 hp",
962 }
963 }
964
965 fn key_update_label(&self) -> &'static [u8] {
966 match self {
967 Self::V1Draft | Self::V1 => b"quic ku",
968 Self::V2 => b"quicv2 ku",
969 }
970 }
971}
972
973impl Default for Version {
974 fn default() -> Self {
975 Self::V1
976 }
977}
978
979#[cfg(test)]
980mod tests {
981 use std::prelude::v1::*;
982
983 use super::PacketKey;
984 use crate::quic::HeaderProtectionKey;
985
986 #[test]
987 fn auto_traits() {
988 fn assert_auto<T: Send + Sync>() {}
989 assert_auto::<Box<dyn PacketKey>>();
990 assert_auto::<Box<dyn HeaderProtectionKey>>();
991 }
992}