1use crate::Algorithm;
4use core::fmt;
5
6#[cfg(feature = "alloc")]
7use crate::certificate;
8
9pub type Result<T> = core::result::Result<T, Error>;
11
12#[derive(Clone, Debug, Eq, PartialEq)]
14#[non_exhaustive]
15pub enum Error {
16 AlgorithmUnknown,
20
21 AlgorithmUnsupported {
29 algorithm: Algorithm,
31 },
32
33 #[cfg(feature = "alloc")]
35 CertificateFieldInvalid(certificate::Field),
36
37 CertificateValidation,
39
40 Crypto,
42
43 Decrypted,
45
46 #[cfg(feature = "ecdsa")]
48 Ecdsa(sec1::Error),
49
50 Encoding(encoding::Error),
52
53 Encrypted,
55
56 FormatEncoding,
58
59 #[cfg(feature = "std")]
61 Io(std::io::ErrorKind),
62
63 Namespace,
65
66 PublicKey,
68
69 Time,
71
72 TrailingData {
74 remaining: usize,
76 },
77
78 Version {
80 number: u32,
82 },
83}
84
85impl fmt::Display for Error {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 match self {
88 Error::AlgorithmUnknown => write!(f, "unknown algorithm"),
89 Error::AlgorithmUnsupported { algorithm } => {
90 write!(f, "unsupported algorithm: {algorithm}")
91 }
92 #[cfg(feature = "alloc")]
93 Error::CertificateFieldInvalid(field) => {
94 write!(f, "certificate field invalid: {field}")
95 }
96 Error::CertificateValidation => write!(f, "certificate validation failed"),
97 Error::Crypto => write!(f, "cryptographic error"),
98 Error::Decrypted => write!(f, "private key is already decrypted"),
99 #[cfg(feature = "ecdsa")]
100 Error::Ecdsa(err) => write!(f, "ECDSA encoding error: {err}"),
101 Error::Encoding(err) => write!(f, "{err}"),
102 Error::Encrypted => write!(f, "private key is encrypted"),
103 Error::FormatEncoding => write!(f, "format encoding error"),
104 #[cfg(feature = "std")]
105 Error::Io(err) => write!(f, "I/O error: {}", std::io::Error::from(*err)),
106 Error::Namespace => write!(f, "namespace invalid"),
107 Error::PublicKey => write!(f, "public key is incorrect"),
108 Error::Time => write!(f, "invalid time"),
109 Error::TrailingData { remaining } => write!(
110 f,
111 "unexpected trailing data at end of message ({remaining} bytes)",
112 ),
113 Error::Version { number: version } => write!(f, "version unsupported: {version}"),
114 }
115 }
116}
117
118impl From<cipher::Error> for Error {
119 fn from(_: cipher::Error) -> Error {
120 Error::Crypto
121 }
122}
123
124impl From<core::array::TryFromSliceError> for Error {
125 fn from(_: core::array::TryFromSliceError) -> Error {
126 Error::Encoding(encoding::Error::Length)
127 }
128}
129
130impl From<core::str::Utf8Error> for Error {
131 fn from(err: core::str::Utf8Error) -> Error {
132 Error::Encoding(err.into())
133 }
134}
135
136impl From<encoding::Error> for Error {
137 fn from(err: encoding::Error) -> Error {
138 Error::Encoding(err)
139 }
140}
141
142impl From<encoding::LabelError> for Error {
143 fn from(err: encoding::LabelError) -> Error {
144 Error::Encoding(err.into())
145 }
146}
147
148impl From<encoding::base64::Error> for Error {
149 fn from(err: encoding::base64::Error) -> Error {
150 Error::Encoding(err.into())
151 }
152}
153
154impl From<encoding::pem::Error> for Error {
155 fn from(err: encoding::pem::Error) -> Error {
156 Error::Encoding(err.into())
157 }
158}
159
160#[cfg(not(feature = "std"))]
161impl From<signature::Error> for Error {
162 fn from(_: signature::Error) -> Error {
163 Error::Crypto
164 }
165}
166
167#[cfg(feature = "std")]
168impl From<signature::Error> for Error {
169 fn from(err: signature::Error) -> Error {
170 use std::error::Error as _;
171
172 err.source()
173 .and_then(|source| source.downcast_ref().cloned())
174 .unwrap_or(Error::Crypto)
175 }
176}
177
178#[cfg(not(feature = "std"))]
179impl From<Error> for signature::Error {
180 fn from(_: Error) -> signature::Error {
181 signature::Error::new()
182 }
183}
184
185#[cfg(feature = "std")]
186impl From<Error> for signature::Error {
187 fn from(err: Error) -> signature::Error {
188 signature::Error::from_source(err)
189 }
190}
191
192#[cfg(feature = "alloc")]
193impl From<alloc::string::FromUtf8Error> for Error {
194 fn from(err: alloc::string::FromUtf8Error) -> Error {
195 Error::Encoding(err.into())
196 }
197}
198
199#[cfg(feature = "ecdsa")]
200impl From<sec1::Error> for Error {
201 fn from(err: sec1::Error) -> Error {
202 Error::Ecdsa(err)
203 }
204}
205
206#[cfg(feature = "rsa")]
207impl From<rsa::errors::Error> for Error {
208 fn from(_: rsa::errors::Error) -> Error {
209 Error::Crypto
210 }
211}
212
213#[cfg(feature = "std")]
214impl From<std::io::Error> for Error {
215 fn from(err: std::io::Error) -> Error {
216 Error::Io(err.kind())
217 }
218}
219
220#[cfg(feature = "std")]
221impl From<std::time::SystemTimeError> for Error {
222 fn from(_: std::time::SystemTimeError) -> Error {
223 Error::Time
224 }
225}
226
227#[cfg(feature = "std")]
228impl std::error::Error for Error {
229 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
230 match self {
231 #[cfg(feature = "ecdsa")]
232 Self::Ecdsa(err) => Some(err),
233 Self::Encoding(err) => Some(err),
234 _ => None,
235 }
236 }
237}