Skip to main content

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>;