1use crate::Algorithm;
4use core::fmt;
5
6#[cfg(feature = "alloc")]
7use crate::certificate;
8
9#[cfg(feature = "ppk")]
10use crate::ppk::PpkParseError;
11
12#[cfg(doc)]
13use crate::HashAlg;
14
15pub type Result<T> = core::result::Result<T, Error>;
17
18#[derive(Clone, Debug, Eq, PartialEq)]
20#[non_exhaustive]
21pub enum Error {
22 AlgorithmUnknown,
26
27 AlgorithmUnsupported {
35 algorithm: Algorithm,
37 },
38
39 #[cfg(feature = "alloc")]
41 CertificateFieldInvalid(certificate::Field),
42
43 CertificateValidation,
45
46 Crypto,
48
49 Decrypted,
51
52 #[cfg(feature = "ecdsa")]
54 Ecdsa(sec1::Error),
55
56 Encoding(encoding::Error),
58
59 Encrypted,
61
62 FormatEncoding,
64
65 HashSize,
67
68 #[cfg(feature = "std")]
70 Io(std::io::ErrorKind),
71
72 Namespace,
74
75 PublicKey,
77
78 #[cfg(feature = "ppk")]
80 Ppk(PpkParseError),
81
82 #[cfg(feature = "rand_core")]
84 RngFailure,
85
86 Time,
88
89 TrailingData {
91 remaining: usize,
93 },
94
95 Version {
97 number: u32,
99 },
100}
101
102impl fmt::Display for Error {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 match self {
105 Error::AlgorithmUnknown => write!(f, "unknown algorithm"),
106 Error::AlgorithmUnsupported { algorithm } => {
107 write!(f, "unsupported algorithm: {algorithm}")
108 }
109 #[cfg(feature = "alloc")]
110 Error::CertificateFieldInvalid(field) => {
111 write!(f, "certificate field invalid: {field}")
112 }
113 Error::CertificateValidation => write!(f, "certificate validation failed"),
114 Error::Crypto => write!(f, "cryptographic error"),
115 Error::Decrypted => write!(f, "private key is already decrypted"),
116 #[cfg(feature = "ecdsa")]
117 Error::Ecdsa(err) => write!(f, "ECDSA encoding error: {err}"),
118 Error::Encoding(err) => write!(f, "{err}"),
119 Error::Encrypted => write!(f, "private key is encrypted"),
120 Error::FormatEncoding => write!(f, "format encoding error"),
121 Error::HashSize => write!(f, "hash is the wrong size for the given algorithm"),
122 #[cfg(feature = "std")]
123 Error::Io(err) => write!(f, "I/O error: {}", std::io::Error::from(*err)),
124 Error::Namespace => write!(f, "namespace invalid"),
125 #[cfg(feature = "ppk")]
126 Error::Ppk(err) => write!(f, "PPK parsing error: {err}"),
127 Error::PublicKey => write!(f, "public key is incorrect"),
128 #[cfg(feature = "rand_core")]
129 Error::RngFailure => write!(f, "random number generator failure"),
130 Error::Time => write!(f, "invalid time"),
131 Error::TrailingData { remaining } => write!(
132 f,
133 "unexpected trailing data at end of message ({remaining} bytes)",
134 ),
135 Error::Version { number: version } => write!(f, "version unsupported: {version}"),
136 }
137 }
138}
139
140impl core::error::Error for Error {
141 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
142 match self {
143 #[cfg(feature = "ecdsa")]
144 Self::Ecdsa(err) => Some(err),
145 Self::Encoding(err) => Some(err),
146 _ => None,
147 }
148 }
149}
150
151impl From<cipher::Error> for Error {
152 fn from(_: cipher::Error) -> Error {
153 Error::Crypto
154 }
155}
156
157impl From<core::array::TryFromSliceError> for Error {
158 fn from(_: core::array::TryFromSliceError) -> Error {
159 Error::Encoding(encoding::Error::Length)
160 }
161}
162
163impl From<core::str::Utf8Error> for Error {
164 fn from(err: core::str::Utf8Error) -> Error {
165 Error::Encoding(err.into())
166 }
167}
168
169impl From<encoding::Error> for Error {
170 fn from(err: encoding::Error) -> Error {
171 Error::Encoding(err)
172 }
173}
174
175impl From<encoding::LabelError> for Error {
176 fn from(err: encoding::LabelError) -> Error {
177 Error::Encoding(err.into())
178 }
179}
180
181impl From<encoding::base64::Error> for Error {
182 fn from(err: encoding::base64::Error) -> Error {
183 Error::Encoding(err.into())
184 }
185}
186
187impl From<encoding::pem::Error> for Error {
188 fn from(err: encoding::pem::Error) -> Error {
189 Error::Encoding(err.into())
190 }
191}
192
193#[cfg(not(feature = "alloc"))]
194impl From<signature::Error> for Error {
195 fn from(_: signature::Error) -> Error {
196 Error::Crypto
197 }
198}
199
200#[cfg(feature = "alloc")]
201impl From<signature::Error> for Error {
202 fn from(err: signature::Error) -> Error {
203 use core::error::Error as _;
204
205 err.source()
206 .and_then(|source| source.downcast_ref().cloned())
207 .unwrap_or(Error::Crypto)
208 }
209}
210
211#[cfg(not(feature = "alloc"))]
212impl From<Error> for signature::Error {
213 fn from(_: Error) -> signature::Error {
214 signature::Error::new()
215 }
216}
217
218#[cfg(feature = "alloc")]
219impl From<Error> for signature::Error {
220 fn from(err: Error) -> signature::Error {
221 signature::Error::from_source(err)
222 }
223}
224
225#[cfg(feature = "alloc")]
226impl From<alloc::string::FromUtf8Error> for Error {
227 fn from(err: alloc::string::FromUtf8Error) -> Error {
228 Error::Encoding(err.into())
229 }
230}
231
232#[cfg(feature = "ecdsa")]
233impl From<sec1::Error> for Error {
234 fn from(err: sec1::Error) -> Error {
235 Error::Ecdsa(err)
236 }
237}
238
239#[cfg(any(feature = "dsa", feature = "rsa"))]
240impl From<encoding::bigint::DecodeError> for Error {
241 fn from(err: encoding::bigint::DecodeError) -> Error {
242 encoding::Error::from(err).into()
243 }
244}
245
246#[cfg(feature = "rsa")]
247impl From<rsa::errors::Error> for Error {
248 fn from(_: rsa::errors::Error) -> Error {
249 Error::Crypto
250 }
251}
252
253#[cfg(feature = "std")]
254impl From<std::io::Error> for Error {
255 fn from(err: std::io::Error) -> Error {
256 Error::Io(err.kind())
257 }
258}
259
260#[cfg(feature = "std")]
261impl From<std::time::SystemTimeError> for Error {
262 fn from(_: std::time::SystemTimeError) -> Error {
263 Error::Time
264 }
265}