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