1use std::fmt;
16use std::io;
17use std::path::PathBuf;
18
19#[derive(Debug)]
21pub enum Error {
22 Io(io::Error),
24 InvalidKeyLength,
26 UnsupportedPkAlgo,
28 UnsupportedKdfAlgo,
30 FileTooShort,
32 FileTooLarge,
34 InvalidCommentHeader,
36 InvalidCommentUtf8,
38 PasswordMismatch,
40 PasswordReadFailed,
42 IncorrectPassphrase,
44 MissingPubKey,
46 KeyMismatch,
48 VerifyFailed,
50 AutolocateFailed(PathBuf, Box<Error>),
52 InvalidKeyName,
54 InvalidPath,
56 CheckFailed,
58 Overflow,
60 Base64Decode(base64ct::Error),
62 Arg(lexopt::Error),
64 InvalidSignatureLength,
66 MissingGzipHeader,
68 MissingGzipSignature,
70 MissingSignatureNewline,
72 KeyringDisabled,
74 InvalidKeyId,
76 RequiredArg(&'static str),
78 MissingMode,
80 InvalidSignatureUtf8,
82 #[cfg(any(target_os = "linux", target_os = "android"))]
84 Keyring(linux_keyutils::KeyError),
85 Crypto(ed25519_compact::Error),
87 Rng(rand_core::OsError),
89 #[cfg(unix)]
90 Nix(nix::errno::Errno),
92 #[cfg(any(target_os = "linux", target_os = "android"))]
94 Landlock(landlock::RulesetError),
95 #[cfg(target_os = "freebsd")]
97 Capsicum(io::Error),
98 #[cfg(target_os = "openbsd")]
100 Pledge(pledge::Error),
101 #[cfg(target_os = "openbsd")]
103 Unveil(unveil::Error),
104}
105
106impl std::error::Error for Error {
107 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
108 match self {
109 Self::Io(err) => Some(err),
110 Self::Base64Decode(err) => Some(err),
111 Self::Arg(err) => Some(err),
112 #[cfg(unix)]
113 Self::Nix(err) => Some(err),
114 #[cfg(any(target_os = "linux", target_os = "android"))]
115 Self::Landlock(err) => Some(err),
116 #[cfg(target_os = "freebsd")]
117 Self::Capsicum(err) => Some(err),
118 #[cfg(target_os = "openbsd")]
119 Self::Pledge(err) => Some(err),
120 #[cfg(target_os = "openbsd")]
121 Self::Unveil(err) => Some(err),
122 _ => None,
123 }
124 }
125}
126
127impl fmt::Display for Error {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 match self {
130 Self::Io(err) => write!(f, "IO error: {err}"),
131 Self::InvalidKeyLength => write!(f, "invalid key length"),
132 Self::UnsupportedPkAlgo => write!(f, "unsupported public key algorithm"),
133 Self::UnsupportedKdfAlgo => write!(f, "unsupported KDF algorithm"),
134 Self::FileTooShort => write!(f, "file too short"),
135 Self::FileTooLarge => write!(f, "file too large (memory limit exceeded)"),
136 Self::InvalidCommentHeader => write!(f, "invalid comment header"),
137 Self::InvalidCommentUtf8 => write!(f, "invalid comment (not utf8)"),
138 Self::InvalidSignatureUtf8 => write!(f, "invalid signature (base64 is not utf8)"),
139 Self::Base64Decode(err) => write!(f, "base64 decode error: {err}"),
140 Self::Arg(err) => write!(f, "argument error: {err}"),
141 Self::PasswordMismatch => write!(f, "password mismatch"),
142 Self::PasswordReadFailed => write!(f, "failed to read password"),
143 Self::IncorrectPassphrase => write!(f, "incorrect passphrase"),
144 Self::MissingPubKey => write!(f, "public key not found"),
145 Self::KeyMismatch => write!(f, "verification failed: checked against wrong key"),
146 Self::VerifyFailed => write!(f, "signature verification failed"),
147 Self::AutolocateFailed(path, err) => {
148 write!(f, "autolocate failed loading {}: {err}", path.display())
149 }
150 Self::InvalidKeyName => write!(f, "invalid key name"),
151 Self::InvalidPath => write!(f, "invalid path"),
152 Self::CheckFailed => write!(f, "checksum check failed"),
153 Self::Overflow => write!(f, "limit exceeded"),
154 Self::InvalidSignatureLength => write!(f, "invalid signature length"),
155 Self::MissingGzipHeader => write!(f, "missing gzip header"),
156 Self::MissingGzipSignature => write!(f, "missing signature in gzip comment"),
157 Self::MissingSignatureNewline => write!(f, "missing newline in signature"),
158 Self::KeyringDisabled => write!(f, "keyring support disabled"),
159 Self::InvalidKeyId => write!(f, "invalid key id"),
160 Self::RequiredArg(arg) => write!(f, "missing required argument: {arg}"),
161 Self::MissingMode => write!(f, "must specify mode"),
162 #[cfg(any(target_os = "linux", target_os = "android"))]
163 Self::Keyring(err) => write!(f, "keyring error: {err:?}"),
164 Self::Crypto(err) => write!(f, "crypto error: {err}"),
165 Self::Rng(err) => write!(f, "rng error: {err}"),
166 #[cfg(unix)]
167 Self::Nix(err) => write!(f, "UNIX error: {err}"),
168 #[cfg(any(target_os = "linux", target_os = "android"))]
169 Self::Landlock(err) => write!(f, "landlock error: {err}"),
170 #[cfg(target_os = "freebsd")]
171 Self::Capsicum(err) => write!(f, "capsicum error: {err}"),
172 #[cfg(target_os = "openbsd")]
173 Self::Pledge(err) => write!(f, "pledge error: {err}"),
174 #[cfg(target_os = "openbsd")]
175 Self::Unveil(err) => write!(f, "unveil error: {err}"),
176 }
177 }
178}
179
180impl From<ed25519_compact::Error> for Error {
181 fn from(err: ed25519_compact::Error) -> Self {
182 Self::Crypto(err)
183 }
184}
185
186#[cfg(unix)]
187impl From<nix::errno::Errno> for Error {
188 fn from(err: nix::errno::Errno) -> Self {
189 Self::Nix(err)
190 }
191}
192
193impl From<io::Error> for Error {
194 fn from(err: io::Error) -> Self {
195 Self::Io(err)
196 }
197}
198
199impl From<base64ct::Error> for Error {
200 fn from(err: base64ct::Error) -> Self {
201 Self::Base64Decode(err)
202 }
203}
204
205impl From<lexopt::Error> for Error {
206 fn from(err: lexopt::Error) -> Self {
207 Self::Arg(err)
208 }
209}
210
211#[cfg(any(target_os = "linux", target_os = "android"))]
212impl From<linux_keyutils::KeyError> for Error {
213 fn from(err: linux_keyutils::KeyError) -> Self {
214 Self::Keyring(err)
215 }
216}
217
218impl From<rand_core::OsError> for Error {
219 fn from(err: rand_core::OsError) -> Self {
220 Self::Rng(err)
221 }
222}
223
224#[cfg(target_os = "openbsd")]
225impl From<pledge::Error> for Error {
226 fn from(err: pledge::Error) -> Self {
227 Self::Pledge(err)
228 }
229}
230
231#[cfg(target_os = "openbsd")]
232impl From<unveil::Error> for Error {
233 fn from(err: unveil::Error) -> Self {
234 Self::Unveil(err)
235 }
236}
237
238#[cfg(any(target_os = "linux", target_os = "android"))]
239impl From<landlock::RulesetError> for Error {
240 fn from(err: landlock::RulesetError) -> Self {
241 Self::Landlock(err)
242 }
243}
244
245pub type Result<T> = std::result::Result<T, Error>;