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::Tls13CipherSuite;
14use crate::tls13::key_schedule::{
15 hkdf_expand_label, hkdf_expand_label_aead_key, hkdf_expand_label_block,
16};
17
18#[cfg(feature = "std")]
19mod connection {
20 use alloc::vec;
21 use alloc::vec::Vec;
22 use core::fmt::{self, Debug};
23 use core::ops::{Deref, DerefMut};
24
25 use pki_types::ServerName;
26
27 use super::{DirectionalKeys, KeyChange, Version};
28 use crate::client::{ClientConfig, ClientConnectionData};
29 use crate::common_state::{CommonState, DEFAULT_BUFFER_LIMIT, Protocol};
30 use crate::conn::{ConnectionCore, SideData};
31 use crate::enums::{AlertDescription, ContentType, ProtocolVersion};
32 use crate::error::Error;
33 use crate::msgs::deframer::buffers::{DeframerVecBuffer, Locator};
34 use crate::msgs::handshake::{ClientExtension, ServerExtension};
35 use crate::msgs::message::InboundPlainMessage;
36 use crate::server::{ServerConfig, ServerConnectionData};
37 use crate::sync::Arc;
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 Self::new_with_alpn(
168 config.clone(),
169 quic_version,
170 name,
171 params,
172 config.alpn_protocols.clone(),
173 )
174 }
175
176 pub fn new_with_alpn(
178 config: Arc<ClientConfig>,
179 quic_version: Version,
180 name: ServerName<'static>,
181 params: Vec<u8>,
182 alpn_protocols: Vec<Vec<u8>>,
183 ) -> Result<Self, Error> {
184 if !config.supports_version(ProtocolVersion::TLSv1_3) {
185 return Err(Error::General(
186 "TLS 1.3 support is required for QUIC".into(),
187 ));
188 }
189
190 if !config.supports_protocol(Protocol::Quic) {
191 return Err(Error::General(
192 "at least one ciphersuite must support QUIC".into(),
193 ));
194 }
195
196 let ext = match quic_version {
197 Version::V1Draft => ClientExtension::TransportParametersDraft(params),
198 Version::V1 | Version::V2 => ClientExtension::TransportParameters(params),
199 };
200
201 let mut inner = ConnectionCore::for_client(
202 config,
203 name,
204 alpn_protocols,
205 vec![ext],
206 Protocol::Quic,
207 )?;
208 inner.common_state.quic.version = quic_version;
209 Ok(Self {
210 inner: inner.into(),
211 })
212 }
213
214 pub fn is_early_data_accepted(&self) -> bool {
220 self.inner.core.is_early_data_accepted()
221 }
222
223 pub fn tls13_tickets_received(&self) -> u32 {
225 self.inner.tls13_tickets_received
226 }
227 }
228
229 impl Deref for ClientConnection {
230 type Target = ConnectionCommon<ClientConnectionData>;
231
232 fn deref(&self) -> &Self::Target {
233 &self.inner
234 }
235 }
236
237 impl DerefMut for ClientConnection {
238 fn deref_mut(&mut self) -> &mut Self::Target {
239 &mut self.inner
240 }
241 }
242
243 impl Debug for ClientConnection {
244 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245 f.debug_struct("quic::ClientConnection")
246 .finish()
247 }
248 }
249
250 impl From<ClientConnection> for Connection {
251 fn from(c: ClientConnection) -> Self {
252 Self::Client(c)
253 }
254 }
255
256 pub struct ServerConnection {
258 inner: ConnectionCommon<ServerConnectionData>,
259 }
260
261 impl ServerConnection {
262 pub fn new(
267 config: Arc<ServerConfig>,
268 quic_version: Version,
269 params: Vec<u8>,
270 ) -> Result<Self, Error> {
271 if !config.supports_version(ProtocolVersion::TLSv1_3) {
272 return Err(Error::General(
273 "TLS 1.3 support is required for QUIC".into(),
274 ));
275 }
276
277 if !config.supports_protocol(Protocol::Quic) {
278 return Err(Error::General(
279 "at least one ciphersuite must support QUIC".into(),
280 ));
281 }
282
283 if config.max_early_data_size != 0 && config.max_early_data_size != 0xffff_ffff {
284 return Err(Error::General(
285 "QUIC sessions must set a max early data of 0 or 2^32-1".into(),
286 ));
287 }
288
289 let ext = match quic_version {
290 Version::V1Draft => ServerExtension::TransportParametersDraft(params),
291 Version::V1 | Version::V2 => ServerExtension::TransportParameters(params),
292 };
293
294 let mut core = ConnectionCore::for_server(config, vec![ext])?;
295 core.common_state.protocol = Protocol::Quic;
296 core.common_state.quic.version = quic_version;
297 Ok(Self { inner: core.into() })
298 }
299
300 pub fn reject_early_data(&mut self) {
306 self.inner.core.reject_early_data()
307 }
308
309 pub fn server_name(&self) -> Option<&str> {
325 self.inner.core.get_sni_str()
326 }
327 }
328
329 impl Deref for ServerConnection {
330 type Target = ConnectionCommon<ServerConnectionData>;
331
332 fn deref(&self) -> &Self::Target {
333 &self.inner
334 }
335 }
336
337 impl DerefMut for ServerConnection {
338 fn deref_mut(&mut self) -> &mut Self::Target {
339 &mut self.inner
340 }
341 }
342
343 impl Debug for ServerConnection {
344 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
345 f.debug_struct("quic::ServerConnection")
346 .finish()
347 }
348 }
349
350 impl From<ServerConnection> for Connection {
351 fn from(c: ServerConnection) -> Self {
352 Self::Server(c)
353 }
354 }
355
356 pub struct ConnectionCommon<Data> {
358 core: ConnectionCore<Data>,
359 deframer_buffer: DeframerVecBuffer,
360 sendable_plaintext: ChunkVecBuffer,
361 }
362
363 impl<Data: SideData> ConnectionCommon<Data> {
364 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
372 self.core
373 .common_state
374 .quic
375 .params
376 .as_ref()
377 .map(|v| v.as_ref())
378 }
379
380 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
382 let suite = self
383 .core
384 .common_state
385 .suite
386 .and_then(|suite| suite.tls13())?;
387 Some(DirectionalKeys::new(
388 suite,
389 suite.quic?,
390 self.core
391 .common_state
392 .quic
393 .early_secret
394 .as_ref()?,
395 self.core.common_state.quic.version,
396 ))
397 }
398
399 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
403 let range = self.deframer_buffer.extend(plaintext);
404
405 self.core.hs_deframer.input_message(
406 InboundPlainMessage {
407 typ: ContentType::Handshake,
408 version: ProtocolVersion::TLSv1_3,
409 payload: &self.deframer_buffer.filled()[range.clone()],
410 },
411 &Locator::new(self.deframer_buffer.filled()),
412 range.end,
413 );
414
415 self.core
416 .hs_deframer
417 .coalesce(self.deframer_buffer.filled_mut())?;
418
419 self.core
420 .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)?;
421
422 Ok(())
423 }
424
425 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
429 self.core
430 .common_state
431 .quic
432 .write_hs(buf)
433 }
434
435 pub fn alert(&self) -> Option<AlertDescription> {
439 self.core.common_state.quic.alert
440 }
441 }
442
443 impl<Data> Deref for ConnectionCommon<Data> {
444 type Target = CommonState;
445
446 fn deref(&self) -> &Self::Target {
447 &self.core.common_state
448 }
449 }
450
451 impl<Data> DerefMut for ConnectionCommon<Data> {
452 fn deref_mut(&mut self) -> &mut Self::Target {
453 &mut self.core.common_state
454 }
455 }
456
457 impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
458 fn from(core: ConnectionCore<Data>) -> Self {
459 Self {
460 core,
461 deframer_buffer: DeframerVecBuffer::default(),
462 sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
463 }
464 }
465 }
466}
467
468#[cfg(feature = "std")]
469pub use connection::{ClientConnection, Connection, ConnectionCommon, ServerConnection};
470
471#[derive(Default)]
472pub(crate) struct Quic {
473 pub(crate) params: Option<Vec<u8>>,
475 pub(crate) alert: Option<AlertDescription>,
476 pub(crate) hs_queue: VecDeque<(bool, Vec<u8>)>,
477 pub(crate) early_secret: Option<OkmBlock>,
478 pub(crate) hs_secrets: Option<Secrets>,
479 pub(crate) traffic_secrets: Option<Secrets>,
480 #[cfg(feature = "std")]
482 pub(crate) returned_traffic_keys: bool,
483 pub(crate) version: Version,
484}
485
486#[cfg(feature = "std")]
487impl Quic {
488 pub(crate) fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
489 while let Some((_, msg)) = self.hs_queue.pop_front() {
490 buf.extend_from_slice(&msg);
491 if let Some(&(true, _)) = self.hs_queue.front() {
492 if self.hs_secrets.is_some() {
493 break;
495 }
496 }
497 }
498
499 if let Some(secrets) = self.hs_secrets.take() {
500 return Some(KeyChange::Handshake {
501 keys: Keys::new(&secrets),
502 });
503 }
504
505 if let Some(mut secrets) = self.traffic_secrets.take() {
506 if !self.returned_traffic_keys {
507 self.returned_traffic_keys = true;
508 let keys = Keys::new(&secrets);
509 secrets.update();
510 return Some(KeyChange::OneRtt {
511 keys,
512 next: secrets,
513 });
514 }
515 }
516
517 None
518 }
519}
520
521#[derive(Clone)]
523pub struct Secrets {
524 pub(crate) client: OkmBlock,
526 pub(crate) server: OkmBlock,
528 suite: &'static Tls13CipherSuite,
530 quic: &'static dyn Algorithm,
531 side: Side,
532 version: Version,
533}
534
535impl Secrets {
536 pub(crate) fn new(
537 client: OkmBlock,
538 server: OkmBlock,
539 suite: &'static Tls13CipherSuite,
540 quic: &'static dyn Algorithm,
541 side: Side,
542 version: Version,
543 ) -> Self {
544 Self {
545 client,
546 server,
547 suite,
548 quic,
549 side,
550 version,
551 }
552 }
553
554 pub fn next_packet_keys(&mut self) -> PacketKeySet {
556 let keys = PacketKeySet::new(self);
557 self.update();
558 keys
559 }
560
561 pub(crate) fn update(&mut self) {
562 self.client = hkdf_expand_label_block(
563 self.suite
564 .hkdf_provider
565 .expander_for_okm(&self.client)
566 .as_ref(),
567 self.version.key_update_label(),
568 &[],
569 );
570 self.server = hkdf_expand_label_block(
571 self.suite
572 .hkdf_provider
573 .expander_for_okm(&self.server)
574 .as_ref(),
575 self.version.key_update_label(),
576 &[],
577 );
578 }
579
580 fn local_remote(&self) -> (&OkmBlock, &OkmBlock) {
581 match self.side {
582 Side::Client => (&self.client, &self.server),
583 Side::Server => (&self.server, &self.client),
584 }
585 }
586}
587
588pub struct DirectionalKeys {
590 pub header: Box<dyn HeaderProtectionKey>,
592 pub packet: Box<dyn PacketKey>,
594}
595
596impl DirectionalKeys {
597 pub(crate) fn new(
598 suite: &'static Tls13CipherSuite,
599 quic: &'static dyn Algorithm,
600 secret: &OkmBlock,
601 version: Version,
602 ) -> Self {
603 let builder = KeyBuilder::new(secret, version, quic, suite.hkdf_provider);
604 Self {
605 header: builder.header_protection_key(),
606 packet: builder.packet_key(),
607 }
608 }
609}
610
611const TAG_LEN: usize = 16;
613
614pub struct Tag([u8; TAG_LEN]);
616
617impl From<&[u8]> for Tag {
618 fn from(value: &[u8]) -> Self {
619 let mut array = [0u8; TAG_LEN];
620 array.copy_from_slice(value);
621 Self(array)
622 }
623}
624
625impl AsRef<[u8]> for Tag {
626 fn as_ref(&self) -> &[u8] {
627 &self.0
628 }
629}
630
631pub trait Algorithm: Send + Sync {
633 fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn PacketKey>;
638
639 fn header_protection_key(&self, key: AeadKey) -> Box<dyn HeaderProtectionKey>;
643
644 fn aead_key_len(&self) -> usize;
648
649 fn fips(&self) -> bool {
651 false
652 }
653}
654
655pub trait HeaderProtectionKey: Send + Sync {
657 fn encrypt_in_place(
678 &self,
679 sample: &[u8],
680 first: &mut u8,
681 packet_number: &mut [u8],
682 ) -> Result<(), Error>;
683
684 fn decrypt_in_place(
706 &self,
707 sample: &[u8],
708 first: &mut u8,
709 packet_number: &mut [u8],
710 ) -> Result<(), Error>;
711
712 fn sample_len(&self) -> usize;
714}
715
716pub trait PacketKey: Send + Sync {
718 fn encrypt_in_place(
726 &self,
727 packet_number: u64,
728 header: &[u8],
729 payload: &mut [u8],
730 ) -> Result<Tag, Error>;
731
732 fn decrypt_in_place<'a>(
740 &self,
741 packet_number: u64,
742 header: &[u8],
743 payload: &'a mut [u8],
744 ) -> Result<&'a [u8], Error>;
745
746 fn tag_len(&self) -> usize;
748
749 fn confidentiality_limit(&self) -> u64;
760
761 fn integrity_limit(&self) -> u64;
770}
771
772pub struct PacketKeySet {
774 pub local: Box<dyn PacketKey>,
776 pub remote: Box<dyn PacketKey>,
778}
779
780impl PacketKeySet {
781 fn new(secrets: &Secrets) -> Self {
782 let (local, remote) = secrets.local_remote();
783 let (version, alg, hkdf) = (secrets.version, secrets.quic, secrets.suite.hkdf_provider);
784 Self {
785 local: KeyBuilder::new(local, version, alg, hkdf).packet_key(),
786 remote: KeyBuilder::new(remote, version, alg, hkdf).packet_key(),
787 }
788 }
789}
790
791pub(crate) struct KeyBuilder<'a> {
792 expander: Box<dyn HkdfExpander>,
793 version: Version,
794 alg: &'a dyn Algorithm,
795}
796
797impl<'a> KeyBuilder<'a> {
798 pub(crate) fn new(
799 secret: &OkmBlock,
800 version: Version,
801 alg: &'a dyn Algorithm,
802 hkdf: &'a dyn Hkdf,
803 ) -> Self {
804 Self {
805 expander: hkdf.expander_for_okm(secret),
806 version,
807 alg,
808 }
809 }
810
811 pub(crate) fn packet_key(&self) -> Box<dyn PacketKey> {
813 let aead_key_len = self.alg.aead_key_len();
814 let packet_key = hkdf_expand_label_aead_key(
815 self.expander.as_ref(),
816 aead_key_len,
817 self.version.packet_key_label(),
818 &[],
819 );
820
821 let packet_iv =
822 hkdf_expand_label(self.expander.as_ref(), self.version.packet_iv_label(), &[]);
823 self.alg
824 .packet_key(packet_key, packet_iv)
825 }
826
827 pub(crate) fn header_protection_key(&self) -> Box<dyn HeaderProtectionKey> {
829 let header_key = hkdf_expand_label_aead_key(
830 self.expander.as_ref(),
831 self.alg.aead_key_len(),
832 self.version.header_key_label(),
833 &[],
834 );
835 self.alg
836 .header_protection_key(header_key)
837 }
838}
839
840#[derive(Clone, Copy)]
842pub struct Suite {
843 pub suite: &'static Tls13CipherSuite,
845 pub quic: &'static dyn Algorithm,
847}
848
849impl Suite {
850 pub fn keys(&self, client_dst_connection_id: &[u8], side: Side, version: Version) -> Keys {
852 Keys::initial(
853 version,
854 self.suite,
855 self.quic,
856 client_dst_connection_id,
857 side,
858 )
859 }
860}
861
862pub struct Keys {
864 pub local: DirectionalKeys,
866 pub remote: DirectionalKeys,
868}
869
870impl Keys {
871 pub fn initial(
873 version: Version,
874 suite: &'static Tls13CipherSuite,
875 quic: &'static dyn Algorithm,
876 client_dst_connection_id: &[u8],
877 side: Side,
878 ) -> Self {
879 const CLIENT_LABEL: &[u8] = b"client in";
880 const SERVER_LABEL: &[u8] = b"server in";
881 let salt = version.initial_salt();
882 let hs_secret = suite
883 .hkdf_provider
884 .extract_from_secret(Some(salt), client_dst_connection_id);
885
886 let secrets = Secrets {
887 version,
888 client: hkdf_expand_label_block(hs_secret.as_ref(), CLIENT_LABEL, &[]),
889 server: hkdf_expand_label_block(hs_secret.as_ref(), SERVER_LABEL, &[]),
890 suite,
891 quic,
892 side,
893 };
894 Self::new(&secrets)
895 }
896
897 fn new(secrets: &Secrets) -> Self {
898 let (local, remote) = secrets.local_remote();
899 Self {
900 local: DirectionalKeys::new(secrets.suite, secrets.quic, local, secrets.version),
901 remote: DirectionalKeys::new(secrets.suite, secrets.quic, remote, secrets.version),
902 }
903 }
904}
905
906pub enum KeyChange {
920 Handshake {
922 keys: Keys,
924 },
925 OneRtt {
927 keys: Keys,
929 next: Secrets,
931 },
932}
933
934#[non_exhaustive]
938#[derive(Clone, Copy, Debug)]
939pub enum Version {
940 V1Draft,
942 V1,
944 V2,
946}
947
948impl Version {
949 fn initial_salt(self) -> &'static [u8; 20] {
950 match self {
951 Self::V1Draft => &[
952 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
954 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
955 ],
956 Self::V1 => &[
957 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
959 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
960 ],
961 Self::V2 => &[
962 0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26,
964 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9,
965 ],
966 }
967 }
968
969 pub(crate) fn packet_key_label(&self) -> &'static [u8] {
971 match self {
972 Self::V1Draft | Self::V1 => b"quic key",
973 Self::V2 => b"quicv2 key",
974 }
975 }
976
977 pub(crate) fn packet_iv_label(&self) -> &'static [u8] {
979 match self {
980 Self::V1Draft | Self::V1 => b"quic iv",
981 Self::V2 => b"quicv2 iv",
982 }
983 }
984
985 pub(crate) fn header_key_label(&self) -> &'static [u8] {
987 match self {
988 Self::V1Draft | Self::V1 => b"quic hp",
989 Self::V2 => b"quicv2 hp",
990 }
991 }
992
993 fn key_update_label(&self) -> &'static [u8] {
994 match self {
995 Self::V1Draft | Self::V1 => b"quic ku",
996 Self::V2 => b"quicv2 ku",
997 }
998 }
999}
1000
1001impl Default for Version {
1002 fn default() -> Self {
1003 Self::V1
1004 }
1005}
1006
1007#[cfg(test)]
1008mod tests {
1009 use std::prelude::v1::*;
1010
1011 use super::PacketKey;
1012 use crate::quic::HeaderProtectionKey;
1013
1014 #[test]
1015 fn auto_traits() {
1016 fn assert_auto<T: Send + Sync>() {}
1017 assert_auto::<Box<dyn PacketKey>>();
1018 assert_auto::<Box<dyn HeaderProtectionKey>>();
1019 }
1020}