rustls_fork_shadow_tls/
error.rs

1use crate::msgs::enums::{AlertDescription, ContentType, HandshakeType};
2use crate::rand;
3
4use std::error::Error as StdError;
5use std::fmt;
6use std::time::SystemTimeError;
7
8/// rustls reports protocol errors using this type.
9#[derive(Debug, PartialEq, Clone)]
10pub enum Error {
11    /// We received a TLS message that isn't valid right now.
12    /// `expect_types` lists the message types we can expect right now.
13    /// `got_type` is the type we found.  This error is typically
14    /// caused by a buggy TLS stack (the peer or this one), a broken
15    /// network, or an attack.
16    InappropriateMessage {
17        /// Which types we expected
18        expect_types: Vec<ContentType>,
19        /// What type we received
20        got_type: ContentType,
21    },
22
23    /// We received a TLS handshake message that isn't valid right now.
24    /// `expect_types` lists the handshake message types we can expect
25    /// right now.  `got_type` is the type we found.
26    InappropriateHandshakeMessage {
27        /// Which handshake type we expected
28        expect_types: Vec<HandshakeType>,
29        /// What handshake type we received
30        got_type: HandshakeType,
31    },
32
33    /// The peer sent us a syntactically incorrect TLS message.
34    CorruptMessage,
35
36    /// The peer sent us a TLS message with invalid contents.
37    CorruptMessagePayload(ContentType),
38
39    /// The peer didn't give us any certificates.
40    NoCertificatesPresented,
41
42    /// The certificate verifier doesn't support the given type of name.
43    UnsupportedNameType,
44
45    /// We couldn't decrypt a message.  This is invariably fatal.
46    DecryptError,
47
48    /// We couldn't encrypt a message because it was larger than the allowed message size.
49    /// This should never happen if the application is using valid record sizes.
50    EncryptError,
51
52    /// The peer doesn't support a protocol version/feature we require.
53    /// The parameter gives a hint as to what version/feature it is.
54    PeerIncompatibleError(String),
55
56    /// The peer deviated from the standard TLS protocol.
57    /// The parameter gives a hint where.
58    PeerMisbehavedError(String),
59
60    /// We received a fatal alert.  This means the peer is unhappy.
61    AlertReceived(AlertDescription),
62
63    /// We received an invalidly encoded certificate from the peer.
64    InvalidCertificateEncoding,
65
66    /// We received a certificate with invalid signature type.
67    InvalidCertificateSignatureType,
68
69    /// We received a certificate with invalid signature.
70    InvalidCertificateSignature,
71
72    /// We received a certificate which includes invalid data.
73    InvalidCertificateData(String),
74
75    /// The presented SCT(s) were invalid.
76    InvalidSct(sct::Error),
77
78    /// A catch-all error for unlikely errors.
79    General(String),
80
81    /// We failed to figure out what time it currently is.
82    FailedToGetCurrentTime,
83
84    /// We failed to acquire random bytes from the system.
85    FailedToGetRandomBytes,
86
87    /// This function doesn't work until the TLS handshake
88    /// is complete.
89    HandshakeNotComplete,
90
91    /// The peer sent an oversized record/fragment.
92    PeerSentOversizedRecord,
93
94    /// An incoming connection did not support any known application protocol.
95    NoApplicationProtocol,
96
97    /// The `max_fragment_size` value supplied in configuration was too small,
98    /// or too large.
99    BadMaxFragmentSize,
100}
101
102fn join<T: fmt::Debug>(items: &[T]) -> String {
103    items
104        .iter()
105        .map(|x| format!("{:?}", x))
106        .collect::<Vec<String>>()
107        .join(" or ")
108}
109
110impl fmt::Display for Error {
111    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112        match *self {
113            Self::InappropriateMessage {
114                ref expect_types,
115                ref got_type,
116            } => write!(
117                f,
118                "received unexpected message: got {:?} when expecting {}",
119                got_type,
120                join::<ContentType>(expect_types)
121            ),
122            Self::InappropriateHandshakeMessage {
123                ref expect_types,
124                ref got_type,
125            } => write!(
126                f,
127                "received unexpected handshake message: got {:?} when expecting {}",
128                got_type,
129                join::<HandshakeType>(expect_types)
130            ),
131            Self::CorruptMessagePayload(ref typ) => {
132                write!(f, "received corrupt message of type {:?}", typ)
133            }
134            Self::PeerIncompatibleError(ref why) => write!(f, "peer is incompatible: {}", why),
135            Self::PeerMisbehavedError(ref why) => write!(f, "peer misbehaved: {}", why),
136            Self::AlertReceived(ref alert) => write!(f, "received fatal alert: {:?}", alert),
137            Self::InvalidCertificateEncoding => {
138                write!(f, "invalid peer certificate encoding")
139            }
140            Self::InvalidCertificateSignatureType => {
141                write!(f, "invalid peer certificate signature type")
142            }
143            Self::InvalidCertificateSignature => {
144                write!(f, "invalid peer certificate signature")
145            }
146            Self::InvalidCertificateData(ref reason) => {
147                write!(f, "invalid peer certificate contents: {}", reason)
148            }
149            Self::CorruptMessage => write!(f, "received corrupt message"),
150            Self::NoCertificatesPresented => write!(f, "peer sent no certificates"),
151            Self::UnsupportedNameType => write!(f, "presented server name type wasn't supported"),
152            Self::DecryptError => write!(f, "cannot decrypt peer's message"),
153            Self::EncryptError => write!(f, "cannot encrypt message"),
154            Self::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
155            Self::HandshakeNotComplete => write!(f, "handshake not complete"),
156            Self::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
157            Self::InvalidSct(ref err) => write!(f, "invalid certificate timestamp: {:?}", err),
158            Self::FailedToGetCurrentTime => write!(f, "failed to get current time"),
159            Self::FailedToGetRandomBytes => write!(f, "failed to get random bytes"),
160            Self::BadMaxFragmentSize => {
161                write!(f, "the supplied max_fragment_size was too small or large")
162            }
163            Self::General(ref err) => write!(f, "unexpected error: {}", err),
164        }
165    }
166}
167
168impl From<SystemTimeError> for Error {
169    #[inline]
170    fn from(_: SystemTimeError) -> Self {
171        Self::FailedToGetCurrentTime
172    }
173}
174
175impl StdError for Error {}
176
177impl From<rand::GetRandomFailed> for Error {
178    fn from(_: rand::GetRandomFailed) -> Self {
179        Self::FailedToGetRandomBytes
180    }
181}
182
183#[cfg(test)]
184mod tests {
185    use super::Error;
186
187    #[test]
188    fn smoke() {
189        use crate::msgs::enums::{AlertDescription, ContentType, HandshakeType};
190        use sct;
191
192        let all = vec![
193            Error::InappropriateMessage {
194                expect_types: vec![ContentType::Alert],
195                got_type: ContentType::Handshake,
196            },
197            Error::InappropriateHandshakeMessage {
198                expect_types: vec![HandshakeType::ClientHello, HandshakeType::Finished],
199                got_type: HandshakeType::ServerHello,
200            },
201            Error::CorruptMessage,
202            Error::CorruptMessagePayload(ContentType::Alert),
203            Error::NoCertificatesPresented,
204            Error::DecryptError,
205            Error::PeerIncompatibleError("no tls1.2".to_string()),
206            Error::PeerMisbehavedError("inconsistent something".to_string()),
207            Error::AlertReceived(AlertDescription::ExportRestriction),
208            Error::InvalidCertificateEncoding,
209            Error::InvalidCertificateSignatureType,
210            Error::InvalidCertificateSignature,
211            Error::InvalidCertificateData("Data".into()),
212            Error::InvalidSct(sct::Error::MalformedSct),
213            Error::General("undocumented error".to_string()),
214            Error::FailedToGetCurrentTime,
215            Error::FailedToGetRandomBytes,
216            Error::HandshakeNotComplete,
217            Error::PeerSentOversizedRecord,
218            Error::NoApplicationProtocol,
219            Error::BadMaxFragmentSize,
220        ];
221
222        for err in all {
223            println!("{:?}:", err);
224            println!("  fmt '{}'", err);
225        }
226    }
227
228    #[test]
229    fn rand_error_mapping() {
230        use super::rand;
231        let err: Error = rand::GetRandomFailed.into();
232        assert_eq!(err, Error::FailedToGetRandomBytes);
233    }
234
235    #[test]
236    fn time_error_mapping() {
237        use std::time::SystemTime;
238
239        let time_error = SystemTime::UNIX_EPOCH
240            .duration_since(SystemTime::now())
241            .unwrap_err();
242        let err: Error = time_error.into();
243        assert_eq!(err, Error::FailedToGetCurrentTime);
244    }
245}