1 use crate::msgs::enums::{AlertDescription, ContentType, HandshakeType};
2 use sct;
3 use std::error::Error;
4 use std::fmt;
5 use webpki;
6
7 /// rustls reports protocol errors using this type.
8 #[derive(Debug, PartialEq, Clone)]
9 pub 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
join<T: fmt::Debug>(items: &[T]) -> String78 fn 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
86 impl fmt::Display for TLSError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result87 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
127 impl Error for TLSError {}
128
129 #[cfg(test)]
130 mod tests {
131 #[test]
smoke()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 }
169