rocket/mtls/error.rs
1use std::fmt;
2use std::num::NonZeroUsize;
3
4use crate::mtls::x509::{self, nom};
5
6/// An error returned by the [`Certificate`](crate::mtls::Certificate) guard.
7///
8/// To retrieve this error in a handler, use an `mtls::Result<Certificate>`
9/// guard type:
10///
11/// ```rust
12/// # extern crate rocket;
13/// # use rocket::get;
14/// use rocket::mtls::{self, Certificate};
15///
16/// #[get("/auth")]
17/// fn auth(cert: mtls::Result<Certificate<'_>>) {
18/// match cert {
19/// Ok(cert) => { /* do something with the client cert */ },
20/// Err(e) => { /* do something with the error */ },
21/// }
22/// }
23/// ```
24#[derive(Debug, Clone)]
25#[non_exhaustive]
26pub enum Error {
27 /// The certificate chain presented by the client had no certificates.
28 Empty,
29 /// The certificate contained neither a subject nor a subjectAlt extension.
30 NoSubject,
31 /// There is no subject and the subjectAlt is not marked as critical.
32 NonCriticalSubjectAlt,
33 /// An error occurred while parsing the certificate.
34 Parse(x509::X509Error),
35 /// The certificate parsed partially but is incomplete.
36 ///
37 /// If `Some(n)`, then `n` more bytes were expected. Otherwise, the number
38 /// of expected bytes is unknown.
39 Incomplete(Option<NonZeroUsize>),
40 /// The certificate contained `.0` bytes of trailing data.
41 Trailing(usize),
42}
43
44impl fmt::Display for Error {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match self {
47 Error::Parse(e) => write!(f, "parse error: {}", e),
48 Error::Incomplete(_) => write!(f, "incomplete certificate data"),
49 Error::Trailing(n) => write!(f, "found {} trailing bytes", n),
50 Error::Empty => write!(f, "empty certificate chain"),
51 Error::NoSubject => write!(f, "empty subject without subjectAlt"),
52 Error::NonCriticalSubjectAlt => write!(f, "empty subject without critical subjectAlt"),
53 }
54 }
55}
56
57impl From<nom::Err<x509::X509Error>> for Error {
58 fn from(e: nom::Err<x509::X509Error>) -> Self {
59 match e {
60 nom::Err::Incomplete(nom::Needed::Unknown) => Error::Incomplete(None),
61 nom::Err::Incomplete(nom::Needed::Size(n)) => Error::Incomplete(Some(n)),
62 nom::Err::Error(e) | nom::Err::Failure(e) => Error::Parse(e),
63 }
64 }
65}
66
67impl std::error::Error for Error {
68 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
69 match self {
70 Error::Parse(e) => Some(e),
71 _ => None
72 }
73 }
74}