diff --git a/quic/s2n-quic-core/src/connection/close.rs b/quic/s2n-quic-core/src/connection/close.rs index 89a4df7589..3d5abf023d 100644 --- a/quic/s2n-quic-core/src/connection/close.rs +++ b/quic/s2n-quic-core/src/connection/close.rs @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use crate::{application, crypto, transport}; +use crate::{application, crypto::tls, transport}; pub use crate::{frame::ConnectionClose, inet::SocketAddress}; /// Provides a hook for applications to rewrite CONNECTION_CLOSE frames @@ -116,8 +116,8 @@ impl Formatter for Production { //# includes replacing any alert with a generic alert, such as //# handshake_failure (0x0128 in QUIC). Endpoints MAY use a generic //# error code to avoid possibly exposing confidential information. - if error.try_into_crypto_error().is_some() { - return transport::Error::from(crypto::CryptoError::HANDSHAKE_FAILURE).into(); + if error.try_into_tls_error().is_some() { + return transport::Error::from(tls::Error::HANDSHAKE_FAILURE).into(); } // only preserve the error code diff --git a/quic/s2n-quic-core/src/connection/error.rs b/quic/s2n-quic-core/src/connection/error.rs index 980106bd01..099c00c6aa 100644 --- a/quic/s2n-quic-core/src/connection/error.rs +++ b/quic/s2n-quic-core/src/connection/error.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - application, connection, crypto::CryptoError, endpoint, frame::ConnectionClose, transport, + application, connection, crypto::packet_protection, endpoint, frame::ConnectionClose, transport, }; use core::{convert::TryInto, fmt, panic, time::Duration}; @@ -469,13 +469,6 @@ impl From for Error { } } -impl From for Error { - #[track_caller] - fn from(error: CryptoError) -> Self { - transport::Error::from(error).into() - } -} - impl<'a> From> for Error { #[track_caller] fn from(error: ConnectionClose) -> Self { @@ -530,7 +523,7 @@ impl From for std::io::ErrorKind { } } -/// Some connection methods may need to indicate both `TransportError`s and `CryptoError`s. This +/// Some connection methods may need to indicate both `ConnectionError`s and `DecryptError`s. This /// enum is used to allow for either error type to be returned as appropriate. #[derive(Clone, Copy, Debug, PartialEq)] pub enum ProcessingError { @@ -548,21 +541,12 @@ impl From for ProcessingError { impl From for ProcessingError { #[track_caller] fn from(inner_error: crate::transport::Error) -> Self { - // Try extracting out the decrypt error from other transport errors - if let Some(error) = inner_error.try_into_crypto_error() { - error.into() - } else { - Self::ConnectionError(inner_error.into()) - } + Self::ConnectionError(inner_error.into()) } } -impl From for ProcessingError { - fn from(inner_error: CryptoError) -> Self { - if inner_error.code == CryptoError::DECRYPT_ERROR.code { - Self::DecryptError - } else { - Self::ConnectionError(inner_error.into()) - } +impl From for ProcessingError { + fn from(_: packet_protection::Error) -> Self { + Self::DecryptError } } diff --git a/quic/s2n-quic-core/src/crypto/application/keyset.rs b/quic/s2n-quic-core/src/crypto/application/keyset.rs index 91cdede8e7..f79caf6127 100644 --- a/quic/s2n-quic-core/src/crypto/application/keyset.rs +++ b/quic/s2n-quic-core/src/crypto/application/keyset.rs @@ -203,7 +203,7 @@ impl KeySet { return Err(transport::Error::AEAD_LIMIT_REACHED.into()); } - Err(err.into()) + Err(err) } } } diff --git a/quic/s2n-quic-core/src/crypto/key.rs b/quic/s2n-quic-core/src/crypto/key.rs index cce195442b..d0927da656 100644 --- a/quic/s2n-quic-core/src/crypto/key.rs +++ b/quic/s2n-quic-core/src/crypto/key.rs @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use crate::crypto::CryptoError; +use crate::crypto::packet_protection; use s2n_codec::encoder::scatter; /// A trait for crypto keys @@ -12,7 +12,7 @@ pub trait Key: Send { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError>; + ) -> Result<(), packet_protection::Error>; /// Encrypt a payload fn encrypt( @@ -20,7 +20,7 @@ pub trait Key: Send { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError>; + ) -> Result<(), packet_protection::Error>; /// Length of the appended tag fn tag_len(&self) -> usize; @@ -37,8 +37,9 @@ pub trait Key: Send { #[cfg(any(test, feature = "testing"))] pub mod testing { use crate::crypto::{ + packet_protection, retry::{IntegrityTag, INTEGRITY_TAG_LEN}, - scatter, CryptoError, HandshakeHeaderKey, HandshakeKey, HeaderKey as CryptoHeaderKey, + scatter, HandshakeHeaderKey, HandshakeKey, HeaderKey as CryptoHeaderKey, HeaderProtectionMask, InitialHeaderKey, InitialKey, OneRttHeaderKey, OneRttKey, RetryKey, ZeroRttHeaderKey, ZeroRttKey, }; @@ -77,9 +78,9 @@ pub mod testing { _packet_number: u64, _header: &[u8], _payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { if self.fail_on_decrypt { - return Err(CryptoError::DECRYPT_ERROR); + return Err(packet_protection::Error::DECRYPT_ERROR); } Ok(()) @@ -91,7 +92,7 @@ pub mod testing { _packet_number: u64, _header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { // copy any bytes into the final slice payload.flatten(); Ok(()) @@ -145,7 +146,7 @@ pub mod testing { fn generate_tag(_payload: &[u8]) -> IntegrityTag { [0u8; INTEGRITY_TAG_LEN] } - fn validate(_payload: &[u8], _tag: IntegrityTag) -> Result<(), CryptoError> { + fn validate(_payload: &[u8], _tag: IntegrityTag) -> Result<(), packet_protection::Error> { Ok(()) } } diff --git a/quic/s2n-quic-core/src/crypto/mod.rs b/quic/s2n-quic-core/src/crypto/mod.rs index bc8e0fc205..9656dd552b 100644 --- a/quic/s2n-quic-core/src/crypto/mod.rs +++ b/quic/s2n-quic-core/src/crypto/mod.rs @@ -132,7 +132,6 @@ //! pub mod application; -pub mod error; pub mod handshake; pub mod header_crypto; pub mod initial; @@ -149,7 +148,6 @@ pub mod zero_rtt; mod tests; pub use application::*; -pub use error::*; pub use handshake::*; pub use header_crypto::*; pub use initial::*; @@ -213,7 +211,7 @@ pub fn encrypt<'a, K: Key>( packet_number_len: PacketNumberLen, header_len: usize, payload: scatter::Buffer<'a>, -) -> Result<(EncryptedPayload<'a>, EncoderBuffer<'a>), CryptoError> { +) -> Result<(EncryptedPayload<'a>, EncoderBuffer<'a>), packet_protection::Error> { let header_with_pn_len = packet_number_len.bytesize() + header_len; let (mut payload, extra) = payload.into_inner(); @@ -254,7 +252,7 @@ pub fn decrypt<'a, K: Key>( key: &K, packet_number: PacketNumber, payload: EncryptedPayload<'a>, -) -> Result<(DecoderBufferMut<'a>, DecoderBufferMut<'a>), CryptoError> { +) -> Result<(DecoderBufferMut<'a>, DecoderBufferMut<'a>), packet_protection::Error> { let (header, payload) = payload.split_mut(); key.decrypt(packet_number.as_crypto_nonce(), header, payload)?; diff --git a/quic/s2n-quic-core/src/crypto/packet_protection.rs b/quic/s2n-quic-core/src/crypto/packet_protection.rs index 4333d43e9f..3c30b1f88b 100644 --- a/quic/s2n-quic-core/src/crypto/packet_protection.rs +++ b/quic/s2n-quic-core/src/crypto/packet_protection.rs @@ -14,3 +14,62 @@ pub const QUIC_IV_LABEL: [u8; 7] = *b"quic iv"; //= https://www.rfc-editor.org/rfc/rfc9001#section-5.1 //# The header protection key uses the "quic hp" label; see Section 5.4. pub const QUIC_HP_LABEL: [u8; 7] = *b"quic hp"; + +use core::fmt; +use s2n_codec::DecoderError; + +/// Error type for errors during removal of packet protection +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "thiserror", derive(thiserror::Error))] +pub struct Error { + pub reason: &'static str, +} + +impl Error { + /// Sets the reason for the `packet_protection::Error` + #[must_use] + pub const fn with_reason(mut self, reason: &'static str) -> Self { + self.reason = reason; + self + } + + pub const DECODE_ERROR: Self = Self { + reason: "DECODE_ERROR", + }; + pub const DECRYPT_ERROR: Self = Self { + reason: "DECRYPT_ERROR", + }; + pub const INTERNAL_ERROR: Self = Self { + reason: "INTERNAL_ERROR", + }; +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if !self.reason.is_empty() { + self.reason.fmt(f) + } else { + write!(f, "packet_protection::Error") + } + } +} + +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut d = f.debug_struct("packet_protection::Error"); + + if !self.reason.is_empty() { + d.field("reason", &self.reason); + } + + d.finish() + } +} + +impl From for Error { + fn from(decoder_error: DecoderError) -> Self { + Self { + reason: decoder_error.into(), + } + } +} diff --git a/quic/s2n-quic-core/src/crypto/retry.rs b/quic/s2n-quic-core/src/crypto/retry.rs index eff75375eb..63b8d859b2 100644 --- a/quic/s2n-quic-core/src/crypto/retry.rs +++ b/quic/s2n-quic-core/src/crypto/retry.rs @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use crate::crypto::CryptoError; +use crate::crypto::packet_protection; use hex_literal::hex; pub const INTEGRITY_TAG_LEN: usize = 16; @@ -9,7 +9,7 @@ pub type IntegrityTag = [u8; INTEGRITY_TAG_LEN]; pub trait RetryKey { fn generate_tag(payload: &[u8]) -> IntegrityTag; - fn validate(payload: &[u8], tag: IntegrityTag) -> Result<(), CryptoError>; + fn validate(payload: &[u8], tag: IntegrityTag) -> Result<(), packet_protection::Error>; } //= https://www.rfc-editor.org/rfc/rfc9001#section-5.8 diff --git a/quic/s2n-quic-core/src/crypto/tests.rs b/quic/s2n-quic-core/src/crypto/tests.rs index 2d20a6274c..fa3c176cc0 100644 --- a/quic/s2n-quic-core/src/crypto/tests.rs +++ b/quic/s2n-quic-core/src/crypto/tests.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - crypto::{scatter, CryptoError, HeaderKey, HeaderProtectionMask, Key, ProtectedPayload}, + crypto::{packet_protection, scatter, HeaderKey, HeaderProtectionMask, Key, ProtectedPayload}, packet::number::{PacketNumber, PacketNumberSpace}, varint::VarInt, }; @@ -43,7 +43,7 @@ fn round_trip() { fn fuzz_unprotect( input: &mut [u8], largest_packet_number: PacketNumber, -) -> Result<(PacketNumber, usize), CryptoError> { +) -> Result<(PacketNumber, usize), packet_protection::Error> { let buffer = DecoderBufferMut::new(input); let header_len = { let peek = buffer.peek(); @@ -64,7 +64,7 @@ fn fuzz_unprotect( packet_number .truncate(largest_packet_number) .filter(|actual| truncated_packet_number.eq(actual)) - .ok_or(CryptoError::DECODE_ERROR)?; + .ok_or(packet_protection::Error::DECODE_ERROR)?; let (_header, _payload) = crate::crypto::decrypt(&FuzzCrypto, packet_number, payload)?; @@ -76,7 +76,7 @@ fn fuzz_protect( header_len: usize, largest_packet_number: PacketNumber, packet_number: PacketNumber, -) -> Result<(), CryptoError> { +) -> Result<(), packet_protection::Error> { let payload_len = input.len(); let mut payload = EncoderBuffer::new(input); payload.set_position(payload_len); @@ -108,7 +108,7 @@ impl Key for FuzzCrypto { packet_number: u64, _header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { let mask = packet_number as u8; for byte in payload.iter_mut() { *byte ^= mask; @@ -121,7 +121,7 @@ impl Key for FuzzCrypto { packet_number: u64, _header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { let payload = payload.flatten(); let (payload, _) = payload.split_mut(); diff --git a/quic/s2n-quic-core/src/crypto/tls.rs b/quic/s2n-quic-core/src/crypto/tls.rs index 0fa62191db..6304fd41ae 100644 --- a/quic/s2n-quic-core/src/crypto/tls.rs +++ b/quic/s2n-quic-core/src/crypto/tls.rs @@ -6,6 +6,9 @@ pub use bytes::{Bytes, BytesMut}; use core::{convert::TryFrom, fmt::Debug}; use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned}; +mod error; +pub use error::Error; + #[cfg(any(test, feature = "testing"))] pub mod testing; diff --git a/quic/s2n-quic-core/src/crypto/error.rs b/quic/s2n-quic-core/src/crypto/tls/error.rs similarity index 89% rename from quic/s2n-quic-core/src/crypto/error.rs rename to quic/s2n-quic-core/src/crypto/tls/error.rs index a738dbbe41..2b4ed0d0dc 100644 --- a/quic/s2n-quic-core/src/crypto/error.rs +++ b/quic/s2n-quic-core/src/crypto/tls/error.rs @@ -4,21 +4,21 @@ use core::fmt; use s2n_codec::DecoderError; -/// Error type for crypto-related errors +/// Error type for TLS-related errors #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "thiserror", derive(thiserror::Error))] -pub struct CryptoError { +pub struct Error { pub reason: &'static str, pub code: u8, } -impl CryptoError { - /// Creates a new `CryptoError` +impl Error { + /// Creates a new `tls::Error` pub const fn new(code: u8) -> Self { Self { code, reason: "" } } - /// Sets the reason for `CryptoError` + /// Sets the reason for `tls::Error` #[must_use] pub const fn with_reason(mut self, reason: &'static str) -> Self { self.reason = reason; @@ -26,21 +26,21 @@ impl CryptoError { } } -impl fmt::Display for CryptoError { +impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if !self.reason.is_empty() { self.reason.fmt(f) } else if let Some(description) = self.description() { description.fmt(f) } else { - write!(f, "CryptoError({})", self.code) + write!(f, "tls::Error({})", self.code) } } } -impl fmt::Debug for CryptoError { +impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut d = f.debug_struct("CryptoError"); + let mut d = f.debug_struct("tls::Error"); d.field("code", &self.code); @@ -56,7 +56,7 @@ impl fmt::Debug for CryptoError { } } -impl From for CryptoError { +impl From for Error { fn from(_: DecoderError) -> Self { Self::DECODE_ERROR } @@ -64,7 +64,7 @@ impl From for CryptoError { macro_rules! alert_descriptions { ($($name:ident = $value:expr),* $(,)?) => { - impl CryptoError { + impl Error { pub fn description(&self) -> Option<&'static str> { match self.code { $( @@ -82,7 +82,7 @@ macro_rules! alert_descriptions { #[test] fn description_test() { $( - assert_eq!(&CryptoError::$name.to_string(), stringify!($name)); + assert_eq!(&Error::$name.to_string(), stringify!($name)); )* } }; diff --git a/quic/s2n-quic-core/src/crypto/tls/null.rs b/quic/s2n-quic-core/src/crypto/tls/null.rs index 0ad3d2ad82..42b6d23d69 100644 --- a/quic/s2n-quic-core/src/crypto/tls/null.rs +++ b/quic/s2n-quic-core/src/crypto/tls/null.rs @@ -303,7 +303,7 @@ mod key { _packet_number: u64, _header: &[u8], _payload: &mut [u8], - ) -> Result<(), crypto::CryptoError> { + ) -> Result<(), crypto::packet_protection::Error> { // Do nothing Ok(()) } @@ -314,7 +314,7 @@ mod key { _packet_number: u64, _header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), crypto::CryptoError> { + ) -> Result<(), crypto::packet_protection::Error> { // copy any extra bytes into the slice payload.flatten(); Ok(()) @@ -422,7 +422,7 @@ mod key { fn validate( _payload: &[u8], _tag: crypto::retry::IntegrityTag, - ) -> Result<(), crypto::CryptoError> { + ) -> Result<(), crypto::packet_protection::Error> { Ok(()) } } diff --git a/quic/s2n-quic-core/src/packet/handshake.rs b/quic/s2n-quic-core/src/packet/handshake.rs index a4843074f6..4e78160382 100644 --- a/quic/s2n-quic-core/src/packet/handshake.rs +++ b/quic/s2n-quic-core/src/packet/handshake.rs @@ -2,7 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - crypto::{CryptoError, EncryptedPayload, HandshakeHeaderKey, HandshakeKey, ProtectedPayload}, + connection::ProcessingError, + crypto::{ + packet_protection, EncryptedPayload, HandshakeHeaderKey, HandshakeKey, ProtectedPayload, + }, packet::{ decoding::HeaderDecoder, encoding::{PacketEncoder, PacketPayloadEncoder}, @@ -94,7 +97,7 @@ impl<'a> ProtectedHandshake<'a> { self, key: &K, largest_acknowledged_packet_number: PacketNumber, - ) -> Result, CryptoError> { + ) -> Result, packet_protection::Error> { let Handshake { version, destination_connection_id, @@ -136,7 +139,7 @@ impl<'a> EncryptedHandshake<'a> { pub fn decrypt( self, crypto: &C, - ) -> Result, transport::Error> { + ) -> Result, ProcessingError> { let Handshake { version, destination_connection_id, @@ -156,9 +159,9 @@ impl<'a> EncryptedHandshake<'a> { //# after removing both packet and header protection as a connection //# error of type PROTOCOL_VIOLATION. if header[0] & super::long::RESERVED_BITS_MASK != 0 { - return Err( - transport::Error::PROTOCOL_VIOLATION.with_reason("reserved bits are non-zero") - ); + return Err(transport::Error::PROTOCOL_VIOLATION + .with_reason("reserved bits are non-zero") + .into()); } let destination_connection_id = destination_connection_id.get(header); diff --git a/quic/s2n-quic-core/src/packet/initial.rs b/quic/s2n-quic-core/src/packet/initial.rs index 089de07f66..38ffc644b3 100644 --- a/quic/s2n-quic-core/src/packet/initial.rs +++ b/quic/s2n-quic-core/src/packet/initial.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - crypto::{CryptoError, EncryptedPayload, InitialHeaderKey, InitialKey, ProtectedPayload}, + crypto::{packet_protection, EncryptedPayload, InitialHeaderKey, InitialKey, ProtectedPayload}, packet::{ decoding::HeaderDecoder, encoding::{PacketEncoder, PacketPayloadEncoder}, @@ -112,7 +112,7 @@ impl<'a> ProtectedInitial<'a> { self, header_key: &H, largest_acknowledged_packet_number: PacketNumber, - ) -> Result, CryptoError> { + ) -> Result, packet_protection::Error> { let Initial { version, destination_connection_id, @@ -160,7 +160,10 @@ impl<'a> ProtectedInitial<'a> { } impl<'a> EncryptedInitial<'a> { - pub fn decrypt(self, crypto: &C) -> Result, CryptoError> { + pub fn decrypt( + self, + crypto: &C, + ) -> Result, packet_protection::Error> { let Initial { version, destination_connection_id, diff --git a/quic/s2n-quic-core/src/packet/retry.rs b/quic/s2n-quic-core/src/packet/retry.rs index 666da11006..bbb1a0e75b 100644 --- a/quic/s2n-quic-core/src/packet/retry.rs +++ b/quic/s2n-quic-core/src/packet/retry.rs @@ -4,9 +4,8 @@ use crate::{ connection, crypto::{ - retry, + packet_protection, retry, retry::{IntegrityTag, RetryKey}, - CryptoError, }, inet::SocketAddress, packet::{ @@ -170,7 +169,7 @@ impl<'a> Retry<'a> { &self, odcid: &connection::InitialId, create_buf: CreateBuf, - ) -> Result<(), CryptoError> + ) -> Result<(), packet_protection::Error> where Crypto: RetryKey, CreateBuf: FnOnce(usize) -> Buf, diff --git a/quic/s2n-quic-core/src/packet/short.rs b/quic/s2n-quic-core/src/packet/short.rs index be2cac1605..8b2e52582f 100644 --- a/quic/s2n-quic-core/src/packet/short.rs +++ b/quic/s2n-quic-core/src/packet/short.rs @@ -3,8 +3,8 @@ use crate::{ connection, - connection::id::ConnectionInfo, - crypto::{CryptoError, EncryptedPayload, OneRttHeaderKey, OneRttKey, ProtectedPayload}, + connection::{id::ConnectionInfo, ProcessingError}, + crypto::{packet_protection, EncryptedPayload, OneRttHeaderKey, OneRttKey, ProtectedPayload}, packet::{ decoding::HeaderDecoder, encoding::{PacketEncoder, PacketPayloadEncoder}, @@ -164,7 +164,7 @@ impl<'a> ProtectedShort<'a> { self, header_key: &H, largest_acknowledged_packet_number: PacketNumber, - ) -> Result, CryptoError> { + ) -> Result, packet_protection::Error> { let Short { spin_bit, destination_connection_id, @@ -197,7 +197,7 @@ impl<'a> ProtectedShort<'a> { } impl<'a> EncryptedShort<'a> { - pub fn decrypt(self, crypto: &C) -> Result, transport::Error> { + pub fn decrypt(self, crypto: &C) -> Result, ProcessingError> { let Short { spin_bit, key_phase, @@ -216,9 +216,9 @@ impl<'a> EncryptedShort<'a> { //# both packet and header protection, as a connection error of type //# PROTOCOL_VIOLATION. if header[0] & RESERVED_BITS_MASK != 0 { - return Err( - transport::Error::PROTOCOL_VIOLATION.with_reason("reserved bits are non-zero") - ); + return Err(transport::Error::PROTOCOL_VIOLATION + .with_reason("reserved bits are non-zero") + .into()); } let destination_connection_id = destination_connection_id.get(header); diff --git a/quic/s2n-quic-core/src/packet/tests.rs b/quic/s2n-quic-core/src/packet/tests.rs index c12ba814d6..932cbd9d12 100644 --- a/quic/s2n-quic-core/src/packet/tests.rs +++ b/quic/s2n-quic-core/src/packet/tests.rs @@ -2,13 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - connection::id::ConnectionInfo, + connection::{id::ConnectionInfo, ProcessingError}, crypto::key::testing, inet::SocketAddress, packet::{ encoding::PacketEncoder, number::PacketNumberSpace, CleartextPacket, ProtectedPacket, }, - transport, }; use bolero::check; use s2n_codec::{DecoderBufferMut, Encoder, EncoderBuffer}; @@ -37,7 +36,7 @@ fn round_trip() { }); } -fn decrypt_packet(packet: ProtectedPacket) -> Result { +fn decrypt_packet(packet: ProtectedPacket) -> Result { use ProtectedPacket::*; match packet { Handshake(packet) => { diff --git a/quic/s2n-quic-core/src/packet/zero_rtt.rs b/quic/s2n-quic-core/src/packet/zero_rtt.rs index 84544297ef..a9c97e1e74 100644 --- a/quic/s2n-quic-core/src/packet/zero_rtt.rs +++ b/quic/s2n-quic-core/src/packet/zero_rtt.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - crypto::{CryptoError, EncryptedPayload, ProtectedPayload, ZeroRttHeaderKey, ZeroRttKey}, + crypto::{packet_protection, EncryptedPayload, ProtectedPayload, ZeroRttHeaderKey, ZeroRttKey}, packet::{ decoding::HeaderDecoder, encoding::{PacketEncoder, PacketPayloadEncoder}, @@ -93,7 +93,7 @@ impl<'a> ProtectedZeroRtt<'a> { self, header_key: &H, largest_acknowledged_packet_number: PacketNumber, - ) -> Result, CryptoError> { + ) -> Result, packet_protection::Error> { let ZeroRtt { version, destination_connection_id, @@ -132,7 +132,10 @@ impl<'a> ProtectedZeroRtt<'a> { } impl<'a> EncryptedZeroRtt<'a> { - pub fn decrypt(self, crypto: &C) -> Result, CryptoError> { + pub fn decrypt( + self, + crypto: &C, + ) -> Result, packet_protection::Error> { let ZeroRtt { version, destination_connection_id, diff --git a/quic/s2n-quic-core/src/transport/error.rs b/quic/s2n-quic-core/src/transport/error.rs index aca53bdc19..8b2faa201b 100644 --- a/quic/s2n-quic-core/src/transport/error.rs +++ b/quic/s2n-quic-core/src/transport/error.rs @@ -4,7 +4,7 @@ #![forbid(unsafe_code)] use crate::{ - crypto::CryptoError, + crypto::tls, frame::ConnectionClose, varint::{VarInt, VarIntError}, }; @@ -159,7 +159,7 @@ macro_rules! impl_errors { $( $code => Some(stringify!($name)), )* - code @ 0x100..=0x1ff => CryptoError::new(code as u8).description(), + code @ 0x100..=0x1ff => tls::Error::new(code as u8).description(), _ => None } } @@ -182,7 +182,7 @@ macro_rules! impl_errors { $( assert_eq!(&Error::$name.to_string(), stringify!($name)); )* - assert_eq!(&Error::from(CryptoError::DECODE_ERROR).to_string(), "DECODE_ERROR"); + assert_eq!(&Error::from(tls::Error::DECODE_ERROR).to_string(), "DECODE_ERROR"); } }; } @@ -334,12 +334,12 @@ impl Error { .with_frame_type(VarInt::from_u32(UNKNOWN_FRAME_TYPE)) } - /// If the [`Error`] contains a [`CryptoError`], it is returned + /// If the [`Error`] contains a [`tls::Error`], it is returned #[inline] - pub fn try_into_crypto_error(self) -> Option { + pub fn try_into_tls_error(self) -> Option { let code = self.code.as_u64(); if (0x100..=0x1ff).contains(&code) { - Some(CryptoError::new(code as u8).with_reason(self.reason)) + Some(tls::Error::new(code as u8).with_reason(self.reason)) } else { None } @@ -374,11 +374,11 @@ impl From for Error { } } -/// Implements conversion from crypto errors +/// Implements conversion from TLS errors /// See `Error::crypto_error` for more details -impl From for Error { - fn from(crypto_error: CryptoError) -> Self { - Self::crypto_error(crypto_error.code).with_reason(crypto_error.reason) +impl From for Error { + fn from(tls_error: tls::Error) -> Self { + Self::crypto_error(tls_error.code).with_reason(tls_error.reason) } } diff --git a/quic/s2n-quic-crypto/src/aead.rs b/quic/s2n-quic-crypto/src/aead.rs index 7702512229..1b8a51aacd 100644 --- a/quic/s2n-quic-crypto/src/aead.rs +++ b/quic/s2n-quic-crypto/src/aead.rs @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -pub use s2n_quic_core::crypto::{scatter, CryptoError as Error}; +pub use s2n_quic_core::crypto::{packet_protection::Error, scatter}; pub type Result = core::result::Result; pub trait Aead { diff --git a/quic/s2n-quic-crypto/src/cipher_suite.rs b/quic/s2n-quic-crypto/src/cipher_suite.rs index 6a72f6e513..d50ceb4aa6 100644 --- a/quic/s2n-quic-crypto/src/cipher_suite.rs +++ b/quic/s2n-quic-crypto/src/cipher_suite.rs @@ -5,7 +5,7 @@ use crate::{aead::Aead, header_key::HeaderKey, hkdf, iv, ring_aead as aead}; use core::fmt; use s2n_quic_core::{ assume, - crypto::{label, scatter, CryptoError}, + crypto::{label, packet_protection, scatter}, }; use zeroize::{Zeroize, Zeroizing}; @@ -130,13 +130,13 @@ macro_rules! impl_cipher_suite { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { let nonce = self.iv.nonce(packet_number); let payload_len = payload .len() .checked_sub(TAG_LEN) - .ok_or_else(|| CryptoError::DECRYPT_ERROR)?; + .ok_or_else(|| packet_protection::Error::DECRYPT_ERROR)?; let (payload, tag) = payload.split_at_mut(payload_len); let tag = { @@ -159,7 +159,7 @@ macro_rules! impl_cipher_suite { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { let nonce = self.iv.nonce(packet_number); self.key.encrypt(&nonce, header, payload)?; Ok(()) diff --git a/quic/s2n-quic-crypto/src/cipher_suite/negotiated.rs b/quic/s2n-quic-crypto/src/cipher_suite/negotiated.rs index 53c934dc48..80038ba40a 100644 --- a/quic/s2n-quic-crypto/src/cipher_suite/negotiated.rs +++ b/quic/s2n-quic-crypto/src/cipher_suite/negotiated.rs @@ -7,7 +7,7 @@ use crate::{ hkdf, ring_aead as aead, }; use core::fmt; -use s2n_quic_core::crypto::{self, scatter, CryptoError}; +use s2n_quic_core::crypto::{self, packet_protection, scatter}; // ignore casing warnings in order to preserve the IANA name #[allow(non_camel_case_types, clippy::all)] @@ -85,7 +85,7 @@ impl crypto::Key for NegotiatedCipherSuite { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { dispatch!(self, |cipher| cipher.decrypt( packet_number, header, @@ -99,7 +99,7 @@ impl crypto::Key for NegotiatedCipherSuite { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { dispatch!(self, |cipher| cipher.encrypt( packet_number, header, diff --git a/quic/s2n-quic-crypto/src/initial.rs b/quic/s2n-quic-crypto/src/initial.rs index f86ac49f34..a2cec38928 100644 --- a/quic/s2n-quic-crypto/src/initial.rs +++ b/quic/s2n-quic-crypto/src/initial.rs @@ -6,7 +6,7 @@ use s2n_quic_core::{ crypto::{ self, label::{CLIENT_IN, SERVER_IN}, - scatter, CryptoError, Key, INITIAL_SALT, + packet_protection, scatter, Key, INITIAL_SALT, }, endpoint, }; @@ -86,7 +86,7 @@ impl Key for InitialKey { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.opener.decrypt(packet_number, header, payload) } @@ -96,7 +96,7 @@ impl Key for InitialKey { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.sealer.encrypt(packet_number, header, payload) } diff --git a/quic/s2n-quic-crypto/src/negotiated.rs b/quic/s2n-quic-crypto/src/negotiated.rs index c9404ce84a..d4c52c5416 100644 --- a/quic/s2n-quic-crypto/src/negotiated.rs +++ b/quic/s2n-quic-crypto/src/negotiated.rs @@ -6,7 +6,7 @@ use crate::{ SecretPair, }; use s2n_quic_core::{ - crypto::{scatter, CryptoError, Key}, + crypto::{packet_protection, scatter, Key}, endpoint, }; @@ -57,7 +57,7 @@ impl Key for KeyPair { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.opener.decrypt(packet_number, header, payload) } @@ -67,7 +67,7 @@ impl Key for KeyPair { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.sealer.encrypt(packet_number, header, payload) } @@ -144,7 +144,7 @@ macro_rules! negotiated_crypto { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), s2n_quic_core::crypto::CryptoError> { + ) -> Result<(), s2n_quic_core::crypto::packet_protection::Error> { self.0.decrypt(packet_number, header, payload) } @@ -154,7 +154,7 @@ macro_rules! negotiated_crypto { packet_number: u64, header: &[u8], payload: &mut s2n_quic_core::crypto::scatter::Buffer, - ) -> Result<(), s2n_quic_core::crypto::CryptoError> { + ) -> Result<(), s2n_quic_core::crypto::packet_protection::Error> { self.0.encrypt(packet_number, header, payload) } diff --git a/quic/s2n-quic-crypto/src/retry.rs b/quic/s2n-quic-crypto/src/retry.rs index 37710591df..50f077664e 100644 --- a/quic/s2n-quic-crypto/src/retry.rs +++ b/quic/s2n-quic-crypto/src/retry.rs @@ -4,9 +4,8 @@ use crate::{constant_time, ring_aead as aead}; use core::convert::TryInto; use s2n_quic_core::crypto::{ - self, + self, packet_protection, retry::{IntegrityTag, NONCE_BYTES, SECRET_KEY_BYTES}, - CryptoError, }; lazy_static::lazy_static! { @@ -31,11 +30,11 @@ impl crypto::RetryKey for RetryKey { .expect("AES_128_GCM tag len should always be 128 bits") } - fn validate(pseudo_packet: &[u8], tag: IntegrityTag) -> Result<(), CryptoError> { + fn validate(pseudo_packet: &[u8], tag: IntegrityTag) -> Result<(), packet_protection::Error> { let expected = Self::generate_tag(pseudo_packet); constant_time::verify_slices_are_equal(&expected, &tag) - .map_err(|_| CryptoError::DECRYPT_ERROR) + .map_err(|_| packet_protection::Error::DECRYPT_ERROR) } } diff --git a/quic/s2n-quic-crypto/src/zero_rtt.rs b/quic/s2n-quic-crypto/src/zero_rtt.rs index 77020a911e..3004ee8ab7 100644 --- a/quic/s2n-quic-crypto/src/zero_rtt.rs +++ b/quic/s2n-quic-crypto/src/zero_rtt.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{cipher_suite::TLS_AES_128_GCM_SHA256 as CipherSuite, header_key::HeaderKey}; -use s2n_quic_core::crypto::{self, scatter, CryptoError, HeaderProtectionMask, Key}; +use s2n_quic_core::crypto::{self, packet_protection, scatter, HeaderProtectionMask, Key}; #[derive(Debug)] pub struct ZeroRttKey(CipherSuite); @@ -25,7 +25,7 @@ impl Key for ZeroRttKey { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.0.decrypt(packet_number, header, payload) } @@ -34,7 +34,7 @@ impl Key for ZeroRttKey { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.0.encrypt(packet_number, header, payload) } diff --git a/quic/s2n-quic-rustls/src/cipher_suite.rs b/quic/s2n-quic-rustls/src/cipher_suite.rs index 7aaf6a3ab6..84b2512d86 100644 --- a/quic/s2n-quic-rustls/src/cipher_suite.rs +++ b/quic/s2n-quic-rustls/src/cipher_suite.rs @@ -3,7 +3,7 @@ use rustls::{cipher_suite as ciphers, quic, CipherSuite, SupportedCipherSuite}; use s2n_codec::Encoder; -use s2n_quic_core::crypto::{self, scatter, tls, CryptoError, HeaderProtectionMask, Key}; +use s2n_quic_core::crypto::{self, packet_protection, scatter, tls, HeaderProtectionMask, Key}; pub struct PacketKey { key: quic::PacketKey, @@ -32,10 +32,10 @@ impl crypto::Key for PacketKey { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { match self.key.decrypt_in_place(packet_number, header, payload) { Ok(_tag) => Ok(()), - Err(_) => Err(CryptoError::DECRYPT_ERROR), + Err(_) => Err(packet_protection::Error::DECRYPT_ERROR), } } @@ -45,7 +45,7 @@ impl crypto::Key for PacketKey { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { let buffer = payload.flatten(); let (payload, _) = buffer.split_mut(); match self.key.encrypt_in_place(packet_number, header, payload) { @@ -53,7 +53,7 @@ impl crypto::Key for PacketKey { buffer.write_slice(tag.as_ref()); Ok(()) } - Err(_) => Err(CryptoError::INTERNAL_ERROR), + Err(_) => Err(packet_protection::Error::INTERNAL_ERROR), } } @@ -122,7 +122,7 @@ impl crypto::Key for PacketKeys { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.opener.decrypt(packet_number, header, payload) } @@ -132,7 +132,7 @@ impl crypto::Key for PacketKeys { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.sealer.encrypt(packet_number, header, payload) } @@ -262,7 +262,7 @@ impl crypto::Key for OneRttKey { packet_number: u64, header: &[u8], payload: &mut [u8], - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.key.decrypt(packet_number, header, payload) } @@ -272,7 +272,7 @@ impl crypto::Key for OneRttKey { packet_number: u64, header: &[u8], payload: &mut scatter::Buffer, - ) -> Result<(), CryptoError> { + ) -> Result<(), packet_protection::Error> { self.key.encrypt(packet_number, header, payload) } diff --git a/quic/s2n-quic-rustls/src/session.rs b/quic/s2n-quic-rustls/src/session.rs index bd9dd39b8e..e3c0dd1954 100644 --- a/quic/s2n-quic-rustls/src/session.rs +++ b/quic/s2n-quic-rustls/src/session.rs @@ -11,7 +11,7 @@ use rustls::quic::{ }; use s2n_quic_core::{ application::ServerName, - crypto::{self, tls, tls::CipherSuite, CryptoError}, + crypto::{self, tls, tls::CipherSuite}, transport, }; @@ -104,11 +104,11 @@ impl Session { self.connection .alert() - .map(|alert| CryptoError { + .map(|alert| tls::Error { code: alert.get_u8(), reason, }) - .unwrap_or(CryptoError::INTERNAL_ERROR) + .unwrap_or(tls::Error::INTERNAL_ERROR) })?; Ok(()) } @@ -122,7 +122,7 @@ impl Session { //# alert, see Section 4.8). let transport_parameters = self.connection.quic_transport_parameters().ok_or_else(|| { - CryptoError::MISSING_EXTENSION.with_reason("Missing QUIC transport parameters") + tls::Error::MISSING_EXTENSION.with_reason("Missing QUIC transport parameters") })?; Ok(tls::ApplicationParameters { diff --git a/quic/s2n-quic-tls/src/callback.rs b/quic/s2n-quic-tls/src/callback.rs index f1ab272e98..162faa3064 100644 --- a/quic/s2n-quic-tls/src/callback.rs +++ b/quic/s2n-quic-tls/src/callback.rs @@ -5,7 +5,7 @@ use bytes::{Bytes, BytesMut}; use core::{ffi::c_void, marker::PhantomData}; use s2n_quic_core::{ application::ServerName, - crypto::{tls, tls::CipherSuite, CryptoError, CryptoSuite}, + crypto::{tls, tls::CipherSuite, CryptoSuite}, endpoint, transport, }; use s2n_quic_crypto::{ @@ -167,7 +167,7 @@ where } let (prk_algo, _aead, cipher_suite) = - get_algo_type(conn).ok_or(CryptoError::INTERNAL_ERROR)?; + get_algo_type(conn).ok_or(tls::Error::INTERNAL_ERROR)?; let secret = Prk::new_less_safe(prk_algo, secret); self.state.secrets = Secrets::Half { secret, id }; self.state.cipher_suite = cipher_suite; @@ -179,7 +179,7 @@ where secret: other_secret, } => { let (prk_algo, aead_algo, cipher_suite) = - get_algo_type(conn).ok_or(CryptoError::INTERNAL_ERROR)?; + get_algo_type(conn).ok_or(tls::Error::INTERNAL_ERROR)?; let secret = Prk::new_less_safe(prk_algo, secret); self.state.cipher_suite = cipher_suite; let pair = match (id, other_id) { @@ -464,7 +464,7 @@ fn get_algo_type( unsafe fn get_application_params<'a>( connection: *mut s2n_connection, -) -> Result, CryptoError> { +) -> Result, tls::Error> { //= https://www.rfc-editor.org/rfc/rfc9001#section-8.1 //# When using ALPN, endpoints MUST immediately close a connection (see //# Section 10.2 of [QUIC-TRANSPORT]) with a no_application_protocol TLS @@ -476,7 +476,7 @@ unsafe fn get_application_params<'a>( //# use this alert, QUIC clients MUST use error 0x178 to terminate a //# connection when ALPN negotiation fails. let transport_parameters = - get_transport_parameters(connection).ok_or(CryptoError::MISSING_EXTENSION)?; + get_transport_parameters(connection).ok_or(tls::Error::MISSING_EXTENSION)?; Ok(tls::ApplicationParameters { transport_parameters, @@ -501,10 +501,10 @@ unsafe fn get_application_params<'a>( //# Application Data <-------> Application Data unsafe fn get_application_protocol<'a>( connection: *mut s2n_connection, -) -> Result<&'a [u8], CryptoError> { +) -> Result<&'a [u8], tls::Error> { let ptr = s2n_get_application_protocol(connection).into_result().ok(); ptr.and_then(|ptr| get_cstr_slice(ptr)) - .ok_or(CryptoError::MISSING_EXTENSION) + .ok_or(tls::Error::MISSING_EXTENSION) } unsafe fn get_transport_parameters<'a>(connection: *mut s2n_connection) -> Option<&'a [u8]> { diff --git a/quic/s2n-quic-tls/src/session.rs b/quic/s2n-quic-tls/src/session.rs index e843ab9ceb..09363a924d 100644 --- a/quic/s2n-quic-tls/src/session.rs +++ b/quic/s2n-quic-tls/src/session.rs @@ -6,7 +6,7 @@ use bytes::BytesMut; use core::{marker::PhantomData, task::Poll}; use s2n_quic_core::{ application::ServerName, - crypto::{tls, tls::CipherSuite, CryptoError, CryptoSuite}, + crypto::{tls, tls::CipherSuite, CryptoSuite}, endpoint, ensure, transport, }; use s2n_quic_crypto::Suite; @@ -135,8 +135,8 @@ impl tls::Session for Session { } Poll::Ready(Err(e)) => Poll::Ready(Err(e .alert() - .map(CryptoError::new) - .unwrap_or(CryptoError::HANDSHAKE_FAILURE) + .map(tls::Error::new) + .unwrap_or(tls::Error::HANDSHAKE_FAILURE) .into())), Poll::Pending => Poll::Pending, } @@ -183,8 +183,8 @@ impl tls::Session for Session { } else { Err(e .alert() - .map(CryptoError::new) - .unwrap_or(CryptoError::HANDSHAKE_FAILURE) + .map(tls::Error::new) + .unwrap_or(tls::Error::HANDSHAKE_FAILURE) .into()) } } diff --git a/quic/s2n-quic-transport/src/connection/errors.rs b/quic/s2n-quic-transport/src/connection/errors.rs deleted file mode 100644 index 1d1ecb4d59..0000000000 --- a/quic/s2n-quic-transport/src/connection/errors.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -//! Defines error types for packet handling inside connections - -use s2n_quic_core::crypto::CryptoError; - -/// Errors that can occur during packet reception -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum PacketHandlingError { - /// A crypto error occurred - CryptoError(CryptoError), -} - -impl From for PacketHandlingError { - fn from(error: CryptoError) -> Self { - Self::CryptoError(error) - } -} diff --git a/quic/s2n-quic-transport/src/connection/mod.rs b/quic/s2n-quic-transport/src/connection/mod.rs index e9ed619282..2f7c91e499 100644 --- a/quic/s2n-quic-transport/src/connection/mod.rs +++ b/quic/s2n-quic-transport/src/connection/mod.rs @@ -18,7 +18,6 @@ mod connection_impl; mod connection_interests; mod connection_timers; mod connection_trait; -mod errors; pub(crate) mod finalization; mod internal_connection_id; pub(crate) mod local_id_registry; diff --git a/quic/s2n-quic-transport/src/endpoint/initial.rs b/quic/s2n-quic-transport/src/endpoint/initial.rs index 0df06e2716..a1dbda2a67 100644 --- a/quic/s2n-quic-transport/src/endpoint/initial.rs +++ b/quic/s2n-quic-transport/src/endpoint/initial.rs @@ -110,8 +110,16 @@ impl endpoint::Endpoint { ); let largest_packet_number = Default::default(); - let packet = packet.unprotect(&initial_header_key, largest_packet_number)?; - let packet = packet.decrypt(&initial_key)?; + // The `packet_protection::Error`s returned by the `unprotect` and `decrypt` methods usually result + // in the packet being dropped, rather than closing the connection. In this case, since there is no + // connection created yet, we map the `packet_protection::Error` to `tls:Error`s that result in the + // connection attempt being aborted rather than just dropping the packets. + let packet = packet + .unprotect(&initial_header_key, largest_packet_number) + .map_err(|_| transport::Error::from(tls::Error::DECODE_ERROR))?; + let packet = packet + .decrypt(&initial_key) + .map_err(|_| transport::Error::from(tls::Error::DECRYPT_ERROR))?; // TODO handle token with stateless retry diff --git a/quic/s2n-quic-transport/src/space/session_context.rs b/quic/s2n-quic-transport/src/space/session_context.rs index 73fd2f033a..bb1d313179 100644 --- a/quic/s2n-quic-transport/src/space/session_context.rs +++ b/quic/s2n-quic-transport/src/space/session_context.rs @@ -487,7 +487,7 @@ impl<'a, Config: endpoint::Config, Pub: event::ConnectionPublisher> //# While [ALPN] only specifies that servers //# use this alert, QUIC clients MUST use error 0x178 to terminate a //# connection when ALPN negotiation fails. - let err = crypto::CryptoError::NO_APPLICATION_PROTOCOL + let err = crypto::tls::Error::NO_APPLICATION_PROTOCOL .with_reason("Missing ALPN protocol") .into(); return Err(err);