Skip to main content

rustica_keys/ssh/
error.rs

1use std::error::Error as StdError;
2use std::{fmt, io, result, string};
3
4/// The `Error` type represents the possible errors that may occur when
5/// working with OpenSSH keys.
6#[derive(Debug)]
7pub struct Error {
8    pub(crate) kind: ErrorKind,
9}
10
11impl Error {
12    pub(crate) fn with_kind(kind: ErrorKind) -> Error {
13        Error { kind }
14    }
15}
16
17/// A type to represent the different kinds of errors.
18#[derive(Debug)]
19pub(crate) enum ErrorKind {
20    Io(io::Error),
21    Decode(base64::DecodeError),
22    Utf8Error(string::FromUtf8Error),
23    InvalidCertType(u32),
24    InvalidFormat,
25    UnexpectedEof,
26    NotCertificate,
27    KeyTypeMismatch,
28    CertificateInvalidSignature,
29    SigningError,
30    EncryptedPrivateKeyNotSupported,
31    UnknownKeyType(String),
32    UnknownCurve(String),
33}
34
35/// A `Result` type alias where the `Err` variant is `Error`
36pub type Result<T> = result::Result<T, Error>;
37
38impl From<io::Error> for Error {
39    fn from(error: io::Error) -> Error {
40        Error {
41            kind: ErrorKind::Io(error),
42        }
43    }
44}
45
46impl From<base64::DecodeError> for Error {
47    fn from(error: base64::DecodeError) -> Error {
48        Error {
49            kind: ErrorKind::Decode(error),
50        }
51    }
52}
53
54impl From<string::FromUtf8Error> for Error {
55    fn from(error: string::FromUtf8Error) -> Error {
56        Error {
57            kind: ErrorKind::Utf8Error(error),
58        }
59    }
60}
61
62impl StdError for Error {
63    fn source(&self) -> Option<&(dyn StdError + 'static)> {
64        match self.kind {
65            ErrorKind::Io(ref e) => e.source(),
66            ErrorKind::Decode(ref e) => e.source(),
67            ErrorKind::Utf8Error(ref e) => e.source(),
68            _ => None,
69        }
70    }
71}
72
73impl fmt::Display for Error {
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        match self.kind {
76            ErrorKind::Io(ref err) => err.fmt(f),
77            ErrorKind::Decode(ref err) => err.fmt(f),
78            ErrorKind::Utf8Error(ref err) => err.fmt(f),
79            ErrorKind::InvalidFormat => write!(f, "Invalid format"),
80            ErrorKind::InvalidCertType(v) => write!(f, "Invalid certificate type with value {}", v),
81            ErrorKind::UnexpectedEof => write!(f, "Unexpected EOF reached while reading data"),
82            ErrorKind::NotCertificate => write!(f, "Not a certificate"),
83            ErrorKind::KeyTypeMismatch => write!(f, "Key type mismatch"),
84            ErrorKind::CertificateInvalidSignature => write!(f, "Certificate is improperly signed"),
85            ErrorKind::SigningError => write!(f, "Could not sign data"),
86            ErrorKind::EncryptedPrivateKeyNotSupported => write!(f, "Encrypted private keys are not supported"),
87            ErrorKind::UnknownKeyType(ref v) => write!(f, "Unknown key type {}", v),
88            ErrorKind::UnknownCurve(ref v) => write!(f, "Unknown curve {}", v),
89        }
90    }
91}