1use crate::SingleOrMultiple;
3use chrono::Duration;
4use std::{error, fmt, io, str, string};
5
6#[derive(Debug)]
7pub enum Error {
11 GenericError(String),
13 DecodeError(DecodeError),
15 ValidationError(ValidationError),
17 JsonError(serde_json::error::Error),
19 DecodeBase64(data_encoding::DecodeError),
21 Utf8(str::Utf8Error),
23 IOError(io::Error),
25 KeyRejected(ring::error::KeyRejected),
27
28 WrongKeyType {
30 expected: String,
32 actual: String,
34 },
35
36 WrongEncryptionOptions {
38 expected: String,
40 actual: String,
42 },
43
44 UnspecifiedCryptographicError,
46 UnsupportedOperation,
48}
49
50#[derive(Debug)]
51pub enum DecodeError {
53 InvalidToken,
55 PartsLengthError {
57 expected: usize,
59 actual: usize,
61 },
62}
63
64#[derive(Debug, Eq, PartialEq, Clone)]
65pub enum ValidationError {
67 InvalidSignature,
69 WrongAlgorithmHeader,
71 MissingRequiredClaims(Vec<String>),
74 Expired(Duration),
77 NotYetValid(Duration),
80 TooOld(Duration),
86 InvalidIssuer(String),
88 InvalidAudience(SingleOrMultiple<String>),
90 KidMissing,
92 KeyNotFound,
94 UnsupportedKeyAlgorithm,
96 MissingAlgorithm,
98}
99
100macro_rules! impl_from_error {
101 ($f:ty, $e:expr) => {
102 impl From<$f> for Error {
103 fn from(f: $f) -> Error {
104 $e(f)
105 }
106 }
107 };
108}
109
110impl_from_error!(String, Error::GenericError);
111impl_from_error!(serde_json::error::Error, Error::JsonError);
112impl_from_error!(data_encoding::DecodeError, Error::DecodeBase64);
113impl_from_error!(str::Utf8Error, Error::Utf8);
114impl_from_error!(ValidationError, Error::ValidationError);
115impl_from_error!(DecodeError, Error::DecodeError);
116impl_from_error!(io::Error, Error::IOError);
117impl_from_error!(ring::error::KeyRejected, Error::KeyRejected);
118
119impl From<ring::error::Unspecified> for Error {
120 fn from(_: ring::error::Unspecified) -> Self {
121 Error::UnspecifiedCryptographicError
122 }
123}
124
125impl From<string::FromUtf8Error> for Error {
126 fn from(e: string::FromUtf8Error) -> Self {
127 Error::Utf8(e.utf8_error())
128 }
129}
130
131impl fmt::Display for Error {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 use crate::Error::*;
134
135 match *self {
136 GenericError(ref err) => fmt::Display::fmt(err, f),
137 JsonError(ref err) => fmt::Display::fmt(err, f),
138 DecodeBase64(ref err) => fmt::Display::fmt(err, f),
139 Utf8(ref err) => fmt::Display::fmt(err, f),
140 DecodeError(ref err) => fmt::Display::fmt(err, f),
141 ValidationError(ref err) => fmt::Display::fmt(err, f),
142 IOError(ref err) => fmt::Display::fmt(err, f),
143 KeyRejected(ref err) => fmt::Display::fmt(err, f),
144 WrongKeyType {
145 ref actual,
146 ref expected,
147 } => write!(
148 f,
149 "{} was expected for this cryptographic operation but {} was provided",
150 expected, actual
151 ),
152 WrongEncryptionOptions {
153 ref actual,
154 ref expected,
155 } => write!(
156 f,
157 "{} was expected for this cryptographic operation but {} was provided",
158 expected, actual
159 ),
160 UnspecifiedCryptographicError => write!(f, "An unspecified cryptographic error"),
161 UnsupportedOperation => write!(f, "This operation is not supported"),
162 }
163 }
164}
165
166impl error::Error for Error {
167 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
168 use crate::Error::*;
169
170 match *self {
171 JsonError(ref err) => Some(err),
172 DecodeBase64(ref err) => Some(err),
173 Utf8(ref err) => Some(err),
174 DecodeError(ref err) => Some(err),
175 ValidationError(ref err) => Some(err),
176 IOError(ref err) => Some(err),
177 _ => None,
178 }
179 }
180}
181
182impl fmt::Display for DecodeError {
183 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184 use self::DecodeError::*;
185
186 match *self {
187 InvalidToken => write!(f, "Invalid token"),
188 PartsLengthError { expected, actual } => write!(
189 f,
190 "Expected {} parts in Compact JSON representation but got {}",
191 expected, actual
192 ),
193 }
194 }
195}
196
197impl error::Error for DecodeError {
198 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
199 None
200 }
201}
202
203impl fmt::Display for ValidationError {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 use crate::ValidationError::*;
206
207 match *self {
208 MissingRequiredClaims(ref fields) => write!(
209 f,
210 "The following claims are required, but missing: {:?}",
211 fields
212 ),
213 Expired(ago) => write!(f, "Token expired {} seconds ago", ago.num_seconds()),
214 NotYetValid(nyv_for) => write!(
215 f,
216 "Token will be valid in {} seconds",
217 nyv_for.num_seconds()
218 ),
219 TooOld(duration) => write!(
220 f,
221 "Token has been considered too old for {} seconds",
222 duration.num_seconds()
223 ),
224 InvalidIssuer(ref iss) => write!(f, "Issuer of token is invalid: {:?}", iss),
225 InvalidAudience(ref aud) => write!(f, "Audience of token is invalid: {:?}", aud),
226 InvalidSignature => write!(f, "Invalid signature"),
227 WrongAlgorithmHeader => write!(
228 f,
229 "Token provided was signed or encrypted with an unexpected algorithm"
230 ),
231 KidMissing => write!(f, "Header is missing kid"),
232 KeyNotFound => write!(f, "Key not found in JWKS"),
233 UnsupportedKeyAlgorithm => write!(f, "Algorithm of JWK not supported"),
234 MissingAlgorithm => write!(
235 f,
236 "An algorithm is needed for verification but was not provided"
237 ),
238 }
239 }
240}
241
242impl error::Error for ValidationError {
243 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
244 None
245 }
246}