krypton/error.rs
1use core::fmt;
2
3/// Errors returned by krypton operations.
4///
5/// Variants are deliberately coarse-grained: cryptographic failures never
6/// reveal whether the password was wrong or the data was tampered with, and
7/// internal details (key material, paths inside the vault) are never included
8/// in error text.
9#[derive(Debug, thiserror::Error)]
10#[non_exhaustive]
11pub enum Error {
12 /// Underlying filesystem I/O failed.
13 #[error("io error")]
14 Io(#[from] std::io::Error),
15
16 /// The container header is malformed or truncated.
17 #[error("invalid or corrupted container header")]
18 InvalidHeader,
19
20 /// The container format version is not supported by this build.
21 #[error("unsupported container version: {0}")]
22 UnsupportedVersion(u32),
23
24 /// The file uses a retired pre-0.4 krypton format. Re-encrypt or
25 /// extract it with krypton 0.3 before use; no retired reader remains.
26 #[error("file uses a retired krypton format")]
27 RetiredFormat,
28
29 /// AEAD authentication failed — wrong password, corrupted data, or
30 /// deliberate tampering.
31 #[error("authentication failed: wrong password or corrupted data")]
32 Authentication,
33
34 /// Symmetric encryption failed.
35 #[error("encryption failed")]
36 Encryption,
37
38 /// Argon2id key derivation failed.
39 #[error("key derivation failed")]
40 KeyDerivation,
41
42 /// KDF parameters are outside the accepted safety bounds.
43 #[error("invalid KDF parameters")]
44 InvalidKdfParams,
45
46 /// A vault-level structure could not be parsed.
47 #[error("invalid vault structure")]
48 InvalidVault,
49
50 /// The vault has already been initialized.
51 #[error("vault already initialized")]
52 VaultExists,
53
54 /// The vault does not exist or is missing required structures.
55 #[error("vault not found")]
56 VaultNotFound,
57
58 /// The operation requires an unlocked vault.
59 #[error("vault is locked")]
60 VaultLocked,
61
62 /// The vault is already unlocked.
63 #[error("vault already unlocked")]
64 VaultUnlocked,
65
66 /// An entry name violates naming rules (empty, too long, path separators,
67 /// `..` components).
68 #[error("invalid entry name: {0}")]
69 InvalidEntryName(String),
70
71 /// The requested entry does not exist in the vault.
72 #[error("entry not found: {0}")]
73 EntryNotFound(String),
74
75 /// An entry with this name already exists.
76 #[error("entry already exists: {0}")]
77 EntryExists(String),
78
79 /// Serialization/deserialization of an encrypted structure failed after
80 /// successful decryption.
81 #[error("malformed decrypted payload")]
82 MalformedPayload,
83
84 /// A user-level operation could not be performed (e.g. password
85 /// confirmation mismatch).
86 #[error("{0}")]
87 Operation(String),
88}
89
90impl Error {
91 /// Convenience constructor for [`Error::InvalidEntryName`].
92 pub(crate) fn invalid_name(name: impl fmt::Display) -> Self {
93 // Only report a redacted preview; never echo arbitrary attacker
94 // controlled bytes at full length.
95 let s = name.to_string();
96 let preview: String = s.chars().take(32).collect();
97 Error::InvalidEntryName(preview)
98 }
99}
100
101/// Result alias used throughout the crate.
102pub type Result<T> = std::result::Result<T, Error>;