image4_pki/
error.rs

1//! Provides error types for the crate.
2
3use super::{DigestAlgo, SigningAlgo};
4use std::fmt;
5
6/// An error returned by the [`FromStr`] implementation on [`DigestAlgo`] when the algorithm's name
7/// isn't recognized.
8///
9/// [`FromStr`]: core::str::FromStr
10#[derive(Clone, Debug)]
11pub struct UnknownDigest(pub Box<str>);
12
13impl std::error::Error for UnknownDigest {}
14
15impl fmt::Display for UnknownDigest {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        f.write_str("unsupported digest name \"")?;
18        fmt::Display::fmt(&self.0.escape_debug(), f)?;
19        f.write_str("\"")
20    }
21}
22
23/// An error returned when either [`SigningKey`] or [`VerifyingKey`] is constructed with unsupported
24/// signing and digest algorithm pair.
25///
26/// [`SigningKey`]: crate::keys::SigningKey
27/// [`VerifyingKey`]: crate::keys::VerifyingKey
28#[derive(Clone, Debug)]
29pub struct UnsupportedDigest {
30    /// The signing algorithm.
31    pub signing_algo: SigningAlgo,
32    /// The digest algorithm.
33    pub digest_algo: DigestAlgo,
34}
35
36impl fmt::Display for UnsupportedDigest {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        write!(
39            f,
40            "a combination of {} signature algorithm and {} digest algorithm isn't supported",
41            self.signing_algo, self.digest_algo
42        )
43    }
44}
45
46impl std::error::Error for UnsupportedDigest {}
47
48/// An error returned when either a public or a private key couldn't be decoded.
49#[derive(Clone, Debug)]
50pub enum DecodeError {
51    /// A DER decoding error.
52    Asn1(der::Error),
53    /// An RSA key couldn't be decoded.
54    Pkcs1(rsa::pkcs1::Error),
55    /// A PKCS#8 key couldn't be decoded.
56    Pkcs8(pkcs8::Error),
57    /// An ECDSA key couldn't be decoded.
58    Sec1(sec1::Error),
59    /// Unknown PEM label.
60    UnexpectedLabel(String),
61}
62
63impl From<der::Error> for DecodeError {
64    fn from(value: der::Error) -> Self {
65        Self::Asn1(value)
66    }
67}
68
69impl From<rsa::pkcs1::Error> for DecodeError {
70    fn from(value: rsa::pkcs1::Error) -> Self {
71        Self::Pkcs1(value)
72    }
73}
74
75impl From<pkcs8::Error> for DecodeError {
76    fn from(value: pkcs8::Error) -> Self {
77        Self::Pkcs8(value)
78    }
79}
80
81impl From<sec1::Error> for DecodeError {
82    fn from(value: sec1::Error) -> Self {
83        Self::Sec1(value)
84    }
85}
86
87impl fmt::Display for DecodeError {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        match self {
90            DecodeError::Asn1(e) => write!(f, "failed to decode PEM file: {e}"),
91            DecodeError::Pkcs1(e) => fmt::Display::fmt(e, f),
92            DecodeError::Pkcs8(e) => fmt::Display::fmt(e, f),
93            DecodeError::Sec1(e) => fmt::Display::fmt(e, f),
94            DecodeError::UnexpectedLabel(label) => write!(f, "unexpected PEM label {label}"),
95        }
96    }
97}
98
99impl std::error::Error for DecodeError {
100    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
101        match self {
102            DecodeError::Asn1(e) => Some(e),
103            DecodeError::Pkcs1(e) => Some(e),
104            DecodeError::Pkcs8(e) => Some(e),
105            DecodeError::Sec1(e) => Some(e),
106            DecodeError::UnexpectedLabel(_) => None,
107        }
108    }
109}