rustls/
error.rs

1use crate::msgs::enums::{AlertDescription, ContentType, HandshakeType};
2use sct;
3use std::error::Error;
4use std::fmt;
5use webpki;
6
7/// rustls reports protocol errors using this type.
8#[derive(Debug, PartialEq, Clone)]
9pub enum TLSError {
10    /// We received a TLS message that isn't valid right now.
11    /// `expect_types` lists the message types we can expect right now.
12    /// `got_type` is the type we found.  This error is typically
13    /// caused by a buggy TLS stack (the peer or this one), a broken
14    /// network, or an attack.
15    InappropriateMessage {
16        /// Which types we expected
17        expect_types: Vec<ContentType>,
18        /// What type we received
19        got_type: ContentType,
20    },
21
22    /// We received a TLS handshake message that isn't valid right now.
23    /// `expect_types` lists the handshake message types we can expect
24    /// right now.  `got_type` is the type we found.
25    InappropriateHandshakeMessage {
26        /// Which handshake type we expected
27        expect_types: Vec<HandshakeType>,
28        /// What handshake type we received
29        got_type: HandshakeType,
30    },
31
32    /// The peer sent us a syntactically incorrect TLS message.
33    CorruptMessage,
34
35    /// The peer sent us a TLS message with invalid contents.
36    CorruptMessagePayload(ContentType),
37
38    /// The peer didn't give us any certificates.
39    NoCertificatesPresented,
40
41    /// We couldn't decrypt a message.  This is invariably fatal.
42    DecryptError,
43
44    /// The peer doesn't support a protocol version/feature we require.
45    /// The parameter gives a hint as to what version/feature it is.
46    PeerIncompatibleError(String),
47
48    /// The peer deviated from the standard TLS protocol.
49    /// The parameter gives a hint where.
50    PeerMisbehavedError(String),
51
52    /// We received a fatal alert.  This means the peer is unhappy.
53    AlertReceived(AlertDescription),
54
55    /// The presented certificate chain is invalid.
56    WebPKIError(webpki::Error),
57
58    /// The presented SCT(s) were invalid.
59    InvalidSCT(sct::Error),
60
61    /// A catch-all error for unlikely errors.
62    General(String),
63
64    /// We failed to figure out what time it currently is.
65    FailedToGetCurrentTime,
66
67    /// This function doesn't work until the TLS handshake
68    /// is complete.
69    HandshakeNotComplete,
70
71    /// The peer sent an oversized record/fragment.
72    PeerSentOversizedRecord,
73
74    /// An incoming connection did not support any known application protocol.
75    NoApplicationProtocol,
76}
77
78fn join<T: fmt::Debug>(items: &[T]) -> String {
79    items
80        .iter()
81        .map(|x| format!("{:?}", x))
82        .collect::<Vec<String>>()
83        .join(" or ")
84}
85
86impl fmt::Display for TLSError {
87    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88        match *self {
89            TLSError::InappropriateMessage {
90                ref expect_types,
91                ref got_type,
92            } => write!(
93                f,
94                "received unexpected message: got {:?} when expecting {}",
95                got_type,
96                join::<ContentType>(expect_types)
97            ),
98            TLSError::InappropriateHandshakeMessage {
99                ref expect_types,
100                ref got_type,
101            } => write!(
102                f,
103                "received unexpected handshake message: got {:?} when expecting {}",
104                got_type,
105                join::<HandshakeType>(expect_types)
106            ),
107            TLSError::CorruptMessagePayload(ref typ) => {
108                write!(f, "received corrupt message of type {:?}", typ)
109            }
110            TLSError::PeerIncompatibleError(ref why) => write!(f, "peer is incompatible: {}", why),
111            TLSError::PeerMisbehavedError(ref why) => write!(f, "peer misbehaved: {}", why),
112            TLSError::AlertReceived(ref alert) => write!(f, "received fatal alert: {:?}", alert),
113            TLSError::WebPKIError(ref err) => write!(f, "invalid certificate: {:?}", err),
114            TLSError::CorruptMessage => write!(f, "received corrupt message"),
115            TLSError::NoCertificatesPresented => write!(f, "peer sent no certificates"),
116            TLSError::DecryptError => write!(f, "cannot decrypt peer's message"),
117            TLSError::PeerSentOversizedRecord => write!(f, "peer sent excess record size"),
118            TLSError::HandshakeNotComplete => write!(f, "handshake not complete"),
119            TLSError::NoApplicationProtocol => write!(f, "peer doesn't support any known protocol"),
120            TLSError::InvalidSCT(ref err) => write!(f, "invalid certificate timestamp: {:?}", err),
121            TLSError::FailedToGetCurrentTime => write!(f, "failed to get current time"),
122            TLSError::General(ref err) => write!(f, "unexpected error: {}", err), // (please file a bug)
123        }
124    }
125}
126
127impl Error for TLSError {}
128
129#[cfg(test)]
130mod tests {
131    #[test]
132    fn smoke() {
133        use super::TLSError;
134        use crate::msgs::enums::{AlertDescription, ContentType, HandshakeType};
135        use sct;
136        use webpki;
137
138        let all = vec![
139            TLSError::InappropriateMessage {
140                expect_types: vec![ContentType::Alert],
141                got_type: ContentType::Handshake,
142            },
143            TLSError::InappropriateHandshakeMessage {
144                expect_types: vec![HandshakeType::ClientHello, HandshakeType::Finished],
145                got_type: HandshakeType::ServerHello,
146            },
147            TLSError::CorruptMessage,
148            TLSError::CorruptMessagePayload(ContentType::Alert),
149            TLSError::NoCertificatesPresented,
150            TLSError::DecryptError,
151            TLSError::PeerIncompatibleError("no tls1.2".to_string()),
152            TLSError::PeerMisbehavedError("inconsistent something".to_string()),
153            TLSError::AlertReceived(AlertDescription::ExportRestriction),
154            TLSError::WebPKIError(webpki::Error::ExtensionValueInvalid),
155            TLSError::InvalidSCT(sct::Error::MalformedSCT),
156            TLSError::General("undocumented error".to_string()),
157            TLSError::FailedToGetCurrentTime,
158            TLSError::HandshakeNotComplete,
159            TLSError::PeerSentOversizedRecord,
160            TLSError::NoApplicationProtocol,
161        ];
162
163        for err in all {
164            println!("{:?}:", err);
165            println!("  fmt '{}'", err);
166        }
167    }
168}