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::Vec;
21 use core::fmt::{self, Debug};
22 use core::ops::{Deref, DerefMut};
23
24 use pki_types::ServerName;
25
26 use super::{DirectionalKeys, KeyChange, Version};
27 use crate::client::{ClientConfig, ClientConnectionData};
28 use crate::common_state::{CommonState, DEFAULT_BUFFER_LIMIT, Protocol};
29 use crate::conn::{ConnectionCore, SideData};
30 use crate::enums::{AlertDescription, ContentType, ProtocolVersion};
31 use crate::error::Error;
32 use crate::msgs::base::Payload;
33 use crate::msgs::deframer::buffers::{DeframerVecBuffer, Locator};
34 use crate::msgs::handshake::{
35 ClientExtensionsInput, ServerExtensionsInput, TransportParameters,
36 };
37 use crate::msgs::message::InboundPlainMessage;
38 use crate::server::{ServerConfig, ServerConnectionData};
39 use crate::sync::Arc;
40 use crate::vecbuf::ChunkVecBuffer;
41
42 #[derive(Debug)]
44 pub enum Connection {
45 Client(ClientConnection),
47 Server(ServerConnection),
49 }
50
51 impl Connection {
52 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
56 match self {
57 Self::Client(conn) => conn.quic_transport_parameters(),
58 Self::Server(conn) => conn.quic_transport_parameters(),
59 }
60 }
61
62 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
64 match self {
65 Self::Client(conn) => conn.zero_rtt_keys(),
66 Self::Server(conn) => conn.zero_rtt_keys(),
67 }
68 }
69
70 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
74 match self {
75 Self::Client(conn) => conn.read_hs(plaintext),
76 Self::Server(conn) => conn.read_hs(plaintext),
77 }
78 }
79
80 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
84 match self {
85 Self::Client(conn) => conn.write_hs(buf),
86 Self::Server(conn) => conn.write_hs(buf),
87 }
88 }
89
90 pub fn alert(&self) -> Option<AlertDescription> {
94 match self {
95 Self::Client(conn) => conn.alert(),
96 Self::Server(conn) => conn.alert(),
97 }
98 }
99
100 #[inline]
116 pub fn export_keying_material<T: AsMut<[u8]>>(
117 &self,
118 output: T,
119 label: &[u8],
120 context: Option<&[u8]>,
121 ) -> Result<T, Error> {
122 match self {
123 Self::Client(conn) => conn
124 .core
125 .export_keying_material(output, label, context),
126 Self::Server(conn) => conn
127 .core
128 .export_keying_material(output, label, context),
129 }
130 }
131 }
132
133 impl Deref for Connection {
134 type Target = CommonState;
135
136 fn deref(&self) -> &Self::Target {
137 match self {
138 Self::Client(conn) => &conn.core.common_state,
139 Self::Server(conn) => &conn.core.common_state,
140 }
141 }
142 }
143
144 impl DerefMut for Connection {
145 fn deref_mut(&mut self) -> &mut Self::Target {
146 match self {
147 Self::Client(conn) => &mut conn.core.common_state,
148 Self::Server(conn) => &mut conn.core.common_state,
149 }
150 }
151 }
152
153 pub struct ClientConnection {
155 inner: ConnectionCommon<ClientConnectionData>,
156 }
157
158 impl ClientConnection {
159 pub fn new(
164 config: Arc<ClientConfig>,
165 quic_version: Version,
166 name: ServerName<'static>,
167 params: Vec<u8>,
168 ) -> Result<Self, Error> {
169 Self::new_with_alpn(
170 config.clone(),
171 quic_version,
172 name,
173 params,
174 config.alpn_protocols.clone(),
175 )
176 }
177
178 pub fn new_with_alpn(
180 config: Arc<ClientConfig>,
181 quic_version: Version,
182 name: ServerName<'static>,
183 params: Vec<u8>,
184 alpn_protocols: Vec<Vec<u8>>,
185 ) -> Result<Self, Error> {
186 if !config.supports_version(ProtocolVersion::TLSv1_3) {
187 return Err(Error::General(
188 "TLS 1.3 support is required for QUIC".into(),
189 ));
190 }
191
192 if !config.supports_protocol(Protocol::Quic) {
193 return Err(Error::General(
194 "at least one ciphersuite must support QUIC".into(),
195 ));
196 }
197
198 let exts = ClientExtensionsInput {
199 transport_parameters: Some(match quic_version {
200 Version::V1Draft => TransportParameters::QuicDraft(Payload::new(params)),
201 Version::V1 | Version::V2 => TransportParameters::Quic(Payload::new(params)),
202 }),
203
204 ..ClientExtensionsInput::from_alpn(alpn_protocols)
205 };
206
207 let mut inner = ConnectionCore::for_client(config, name, exts, Protocol::Quic)?;
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 exts = ServerExtensionsInput {
290 transport_parameters: Some(match quic_version {
291 Version::V1Draft => TransportParameters::QuicDraft(Payload::new(params)),
292 Version::V1 | Version::V2 => TransportParameters::Quic(Payload::new(params)),
293 }),
294 };
295
296 let mut core = ConnectionCore::for_server(config, exts)?;
297 core.common_state.protocol = Protocol::Quic;
298 core.common_state.quic.version = quic_version;
299 Ok(Self { inner: core.into() })
300 }
301
302 pub fn reject_early_data(&mut self) {
308 self.inner.core.reject_early_data()
309 }
310
311 pub fn server_name(&self) -> Option<&str> {
327 self.inner.core.get_sni_str()
328 }
329
330 pub fn get_upstream_addr(&self) -> Option<std::string::String> {
332 match self.inner
333 .core
334 .common_state
335 .jls_authed {
336 crate::jls::JlsState::AuthFailed(ref addr) => addr.clone(),
337 _ => None,
338 }
339 }
340 pub fn jls_chosen_usesr(&self) -> Option<&crate::jls::JlsUser> {
342
343 match self.inner
344 .core
345 .common_state.jls_authed {
346 crate::jls::JlsState::AuthSuccess(ref user) => Some(user),
347 _ => None,
348 }
349
350 }
351 }
352
353 impl Deref for ServerConnection {
354 type Target = ConnectionCommon<ServerConnectionData>;
355
356 fn deref(&self) -> &Self::Target {
357 &self.inner
358 }
359 }
360
361 impl DerefMut for ServerConnection {
362 fn deref_mut(&mut self) -> &mut Self::Target {
363 &mut self.inner
364 }
365 }
366
367 impl Debug for ServerConnection {
368 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
369 f.debug_struct("quic::ServerConnection")
370 .finish()
371 }
372 }
373
374 impl From<ServerConnection> for Connection {
375 fn from(c: ServerConnection) -> Self {
376 Self::Server(c)
377 }
378 }
379
380 pub struct ConnectionCommon<Data> {
382 core: ConnectionCore<Data>,
383 deframer_buffer: DeframerVecBuffer,
384 sendable_plaintext: ChunkVecBuffer,
385 }
386
387 impl<Data: SideData> ConnectionCommon<Data> {
388 pub fn quic_transport_parameters(&self) -> Option<&[u8]> {
396 self.core
397 .common_state
398 .quic
399 .params
400 .as_ref()
401 .map(|v| v.as_ref())
402 }
403
404 pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys> {
406 let suite = self
407 .core
408 .common_state
409 .suite
410 .and_then(|suite| suite.tls13())?;
411 Some(DirectionalKeys::new(
412 suite,
413 suite.quic?,
414 self.core
415 .common_state
416 .quic
417 .early_secret
418 .as_ref()?,
419 self.core.common_state.quic.version,
420 ))
421 }
422
423 pub fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
427 let range = self.deframer_buffer.extend(plaintext);
428
429 self.core.hs_deframer.input_message(
430 InboundPlainMessage {
431 typ: ContentType::Handshake,
432 version: ProtocolVersion::TLSv1_3,
433 payload: &self.deframer_buffer.filled()[range.clone()],
434 },
435 &Locator::new(self.deframer_buffer.filled()),
436 range.end,
437 );
438
439 self.core
440 .hs_deframer
441 .coalesce(self.deframer_buffer.filled_mut())?;
442
443 self.core
444 .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)?;
445
446 Ok(())
447 }
448
449 pub fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
453 self.core
454 .common_state
455 .quic
456 .write_hs(buf)
457 }
458
459 pub fn alert(&self) -> Option<AlertDescription> {
463 self.core.common_state.quic.alert
464 }
465 }
466
467 impl<Data> Deref for ConnectionCommon<Data> {
468 type Target = CommonState;
469
470 fn deref(&self) -> &Self::Target {
471 &self.core.common_state
472 }
473 }
474
475 impl<Data> DerefMut for ConnectionCommon<Data> {
476 fn deref_mut(&mut self) -> &mut Self::Target {
477 &mut self.core.common_state
478 }
479 }
480
481 impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
482 fn from(core: ConnectionCore<Data>) -> Self {
483 Self {
484 core,
485 deframer_buffer: DeframerVecBuffer::default(),
486 sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
487 }
488 }
489 }
490}
491
492#[cfg(feature = "std")]
493pub use connection::{ClientConnection, Connection, ConnectionCommon, ServerConnection};
494
495#[derive(Default)]
496pub(crate) struct Quic {
497 pub(crate) params: Option<Vec<u8>>,
499 pub(crate) alert: Option<AlertDescription>,
500 pub(crate) hs_queue: VecDeque<(bool, Vec<u8>)>,
501 pub(crate) early_secret: Option<OkmBlock>,
502 pub(crate) hs_secrets: Option<Secrets>,
503 pub(crate) traffic_secrets: Option<Secrets>,
504 #[cfg(feature = "std")]
506 pub(crate) returned_traffic_keys: bool,
507 pub(crate) version: Version,
508}
509
510#[cfg(feature = "std")]
511impl Quic {
512 pub(crate) fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<KeyChange> {
513 while let Some((_, msg)) = self.hs_queue.pop_front() {
514 buf.extend_from_slice(&msg);
515 if let Some(&(true, _)) = self.hs_queue.front() {
516 if self.hs_secrets.is_some() {
517 break;
519 }
520 }
521 }
522
523 if let Some(secrets) = self.hs_secrets.take() {
524 return Some(KeyChange::Handshake {
525 keys: Keys::new(&secrets),
526 });
527 }
528
529 if let Some(mut secrets) = self.traffic_secrets.take() {
530 if !self.returned_traffic_keys {
531 self.returned_traffic_keys = true;
532 let keys = Keys::new(&secrets);
533 secrets.update();
534 return Some(KeyChange::OneRtt {
535 keys,
536 next: secrets,
537 });
538 }
539 }
540
541 None
542 }
543}
544
545#[derive(Clone)]
547pub struct Secrets {
548 pub(crate) client: OkmBlock,
550 pub(crate) server: OkmBlock,
552 suite: &'static Tls13CipherSuite,
554 quic: &'static dyn Algorithm,
555 side: Side,
556 version: Version,
557}
558
559impl Secrets {
560 pub(crate) fn new(
561 client: OkmBlock,
562 server: OkmBlock,
563 suite: &'static Tls13CipherSuite,
564 quic: &'static dyn Algorithm,
565 side: Side,
566 version: Version,
567 ) -> Self {
568 Self {
569 client,
570 server,
571 suite,
572 quic,
573 side,
574 version,
575 }
576 }
577
578 pub fn next_packet_keys(&mut self) -> PacketKeySet {
580 let keys = PacketKeySet::new(self);
581 self.update();
582 keys
583 }
584
585 pub(crate) fn update(&mut self) {
586 self.client = hkdf_expand_label_block(
587 self.suite
588 .hkdf_provider
589 .expander_for_okm(&self.client)
590 .as_ref(),
591 self.version.key_update_label(),
592 &[],
593 );
594 self.server = hkdf_expand_label_block(
595 self.suite
596 .hkdf_provider
597 .expander_for_okm(&self.server)
598 .as_ref(),
599 self.version.key_update_label(),
600 &[],
601 );
602 }
603
604 fn local_remote(&self) -> (&OkmBlock, &OkmBlock) {
605 match self.side {
606 Side::Client => (&self.client, &self.server),
607 Side::Server => (&self.server, &self.client),
608 }
609 }
610}
611
612pub struct DirectionalKeys {
614 pub header: Box<dyn HeaderProtectionKey>,
616 pub packet: Box<dyn PacketKey>,
618}
619
620impl DirectionalKeys {
621 pub(crate) fn new(
622 suite: &'static Tls13CipherSuite,
623 quic: &'static dyn Algorithm,
624 secret: &OkmBlock,
625 version: Version,
626 ) -> Self {
627 let builder = KeyBuilder::new(secret, version, quic, suite.hkdf_provider);
628 Self {
629 header: builder.header_protection_key(),
630 packet: builder.packet_key(),
631 }
632 }
633}
634
635const TAG_LEN: usize = 16;
637
638pub struct Tag([u8; TAG_LEN]);
640
641impl From<&[u8]> for Tag {
642 fn from(value: &[u8]) -> Self {
643 let mut array = [0u8; TAG_LEN];
644 array.copy_from_slice(value);
645 Self(array)
646 }
647}
648
649impl AsRef<[u8]> for Tag {
650 fn as_ref(&self) -> &[u8] {
651 &self.0
652 }
653}
654
655pub trait Algorithm: Send + Sync {
657 fn packet_key(&self, key: AeadKey, iv: Iv) -> Box<dyn PacketKey>;
662
663 fn header_protection_key(&self, key: AeadKey) -> Box<dyn HeaderProtectionKey>;
667
668 fn aead_key_len(&self) -> usize;
672
673 fn fips(&self) -> bool {
675 false
676 }
677}
678
679pub trait HeaderProtectionKey: Send + Sync {
681 fn encrypt_in_place(
702 &self,
703 sample: &[u8],
704 first: &mut u8,
705 packet_number: &mut [u8],
706 ) -> Result<(), Error>;
707
708 fn decrypt_in_place(
730 &self,
731 sample: &[u8],
732 first: &mut u8,
733 packet_number: &mut [u8],
734 ) -> Result<(), Error>;
735
736 fn sample_len(&self) -> usize;
738}
739
740pub trait PacketKey: Send + Sync {
742 fn encrypt_in_place(
750 &self,
751 packet_number: u64,
752 header: &[u8],
753 payload: &mut [u8],
754 ) -> Result<Tag, Error>;
755
756 fn encrypt_in_place_for_path(
766 &self,
767 _path_id: u32,
768 _packet_number: u64,
769 _header: &[u8],
770 _payload: &mut [u8],
771 ) -> Result<Tag, Error> {
772 Err(Error::EncryptError)
773 }
774
775 fn decrypt_in_place<'a>(
783 &self,
784 packet_number: u64,
785 header: &[u8],
786 payload: &'a mut [u8],
787 ) -> Result<&'a [u8], Error>;
788
789 fn decrypt_in_place_for_path<'a>(
800 &self,
801 _path_id: u32,
802 _packet_number: u64,
803 _header: &[u8],
804 _payload: &'a mut [u8],
805 ) -> Result<&'a [u8], Error> {
806 Err(Error::DecryptError)
807 }
808
809 fn tag_len(&self) -> usize;
811
812 fn confidentiality_limit(&self) -> u64;
823
824 fn integrity_limit(&self) -> u64;
833}
834
835pub struct PacketKeySet {
837 pub local: Box<dyn PacketKey>,
839 pub remote: Box<dyn PacketKey>,
841}
842
843impl PacketKeySet {
844 fn new(secrets: &Secrets) -> Self {
845 let (local, remote) = secrets.local_remote();
846 let (version, alg, hkdf) = (secrets.version, secrets.quic, secrets.suite.hkdf_provider);
847 Self {
848 local: KeyBuilder::new(local, version, alg, hkdf).packet_key(),
849 remote: KeyBuilder::new(remote, version, alg, hkdf).packet_key(),
850 }
851 }
852}
853
854pub(crate) struct KeyBuilder<'a> {
855 expander: Box<dyn HkdfExpander>,
856 version: Version,
857 alg: &'a dyn Algorithm,
858}
859
860impl<'a> KeyBuilder<'a> {
861 pub(crate) fn new(
862 secret: &OkmBlock,
863 version: Version,
864 alg: &'a dyn Algorithm,
865 hkdf: &'a dyn Hkdf,
866 ) -> Self {
867 Self {
868 expander: hkdf.expander_for_okm(secret),
869 version,
870 alg,
871 }
872 }
873
874 pub(crate) fn packet_key(&self) -> Box<dyn PacketKey> {
876 let aead_key_len = self.alg.aead_key_len();
877 let packet_key = hkdf_expand_label_aead_key(
878 self.expander.as_ref(),
879 aead_key_len,
880 self.version.packet_key_label(),
881 &[],
882 );
883
884 let packet_iv =
885 hkdf_expand_label(self.expander.as_ref(), self.version.packet_iv_label(), &[]);
886 self.alg
887 .packet_key(packet_key, packet_iv)
888 }
889
890 pub(crate) fn header_protection_key(&self) -> Box<dyn HeaderProtectionKey> {
892 let header_key = hkdf_expand_label_aead_key(
893 self.expander.as_ref(),
894 self.alg.aead_key_len(),
895 self.version.header_key_label(),
896 &[],
897 );
898 self.alg
899 .header_protection_key(header_key)
900 }
901}
902
903#[derive(Clone, Copy)]
905pub struct Suite {
906 pub suite: &'static Tls13CipherSuite,
908 pub quic: &'static dyn Algorithm,
910}
911
912impl Suite {
913 pub fn keys(&self, client_dst_connection_id: &[u8], side: Side, version: Version) -> Keys {
915 Keys::initial(
916 version,
917 self.suite,
918 self.quic,
919 client_dst_connection_id,
920 side,
921 )
922 }
923}
924
925pub struct Keys {
927 pub local: DirectionalKeys,
929 pub remote: DirectionalKeys,
931}
932
933impl Keys {
934 pub fn initial(
936 version: Version,
937 suite: &'static Tls13CipherSuite,
938 quic: &'static dyn Algorithm,
939 client_dst_connection_id: &[u8],
940 side: Side,
941 ) -> Self {
942 const CLIENT_LABEL: &[u8] = b"client in";
943 const SERVER_LABEL: &[u8] = b"server in";
944 let salt = version.initial_salt();
945 let hs_secret = suite
946 .hkdf_provider
947 .extract_from_secret(Some(salt), client_dst_connection_id);
948
949 let secrets = Secrets {
950 version,
951 client: hkdf_expand_label_block(hs_secret.as_ref(), CLIENT_LABEL, &[]),
952 server: hkdf_expand_label_block(hs_secret.as_ref(), SERVER_LABEL, &[]),
953 suite,
954 quic,
955 side,
956 };
957 Self::new(&secrets)
958 }
959
960 fn new(secrets: &Secrets) -> Self {
961 let (local, remote) = secrets.local_remote();
962 Self {
963 local: DirectionalKeys::new(secrets.suite, secrets.quic, local, secrets.version),
964 remote: DirectionalKeys::new(secrets.suite, secrets.quic, remote, secrets.version),
965 }
966 }
967}
968
969pub enum KeyChange {
983 Handshake {
985 keys: Keys,
987 },
988 OneRtt {
990 keys: Keys,
992 next: Secrets,
994 },
995}
996
997#[non_exhaustive]
1001#[derive(Clone, Copy, Debug, Default)]
1002pub enum Version {
1003 V1Draft,
1005 #[default]
1007 V1,
1008 V2,
1010}
1011
1012impl Version {
1013 fn initial_salt(self) -> &'static [u8; 20] {
1014 match self {
1015 Self::V1Draft => &[
1016 0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
1018 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99,
1019 ],
1020 Self::V1 => &[
1021 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8,
1023 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a,
1024 ],
1025 Self::V2 => &[
1026 0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26,
1028 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9,
1029 ],
1030 }
1031 }
1032
1033 pub(crate) fn packet_key_label(&self) -> &'static [u8] {
1035 match self {
1036 Self::V1Draft | Self::V1 => b"quic key",
1037 Self::V2 => b"quicv2 key",
1038 }
1039 }
1040
1041 pub(crate) fn packet_iv_label(&self) -> &'static [u8] {
1043 match self {
1044 Self::V1Draft | Self::V1 => b"quic iv",
1045 Self::V2 => b"quicv2 iv",
1046 }
1047 }
1048
1049 pub(crate) fn header_key_label(&self) -> &'static [u8] {
1051 match self {
1052 Self::V1Draft | Self::V1 => b"quic hp",
1053 Self::V2 => b"quicv2 hp",
1054 }
1055 }
1056
1057 fn key_update_label(&self) -> &'static [u8] {
1058 match self {
1059 Self::V1Draft | Self::V1 => b"quic ku",
1060 Self::V2 => b"quicv2 ku",
1061 }
1062 }
1063}
1064
1065#[cfg(test)]
1066mod tests {
1067 use std::prelude::v1::*;
1068
1069 use super::PacketKey;
1070 use crate::quic::HeaderProtectionKey;
1071
1072 #[test]
1073 fn auto_traits() {
1074 fn assert_auto<T: Send + Sync>() {}
1075 assert_auto::<Box<dyn PacketKey>>();
1076 assert_auto::<Box<dyn HeaderProtectionKey>>();
1077 }
1078}