Skip to main content

shadow_crypt_core/
errors.rs

1use std::{error::Error, fmt::Display};
2
3#[derive(Debug)]
4pub enum HeaderError {
5    InsufficientBytes,
6    InvalidData,
7    FilenameTooLong,
8    MetadataTooLong,
9}
10
11impl std::fmt::Display for HeaderError {
12    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13        match self {
14            HeaderError::InsufficientBytes => write!(f, "Insufficient bytes to read header"),
15            HeaderError::InvalidData => write!(f, "Invalid header data"),
16            HeaderError::FilenameTooLong => {
17                write!(f, "Encrypted filename is too long to fit in the header")
18            }
19            HeaderError::MetadataTooLong => {
20                write!(f, "Encrypted metadata is too long to fit in the header")
21            }
22        }
23    }
24}
25
26impl std::error::Error for HeaderError {}
27
28#[derive(Debug)]
29pub enum KeyDerivationError {
30    InvalidParameters(String),
31    DerivationFailed(String),
32}
33
34impl std::fmt::Display for KeyDerivationError {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        match self {
37            KeyDerivationError::InvalidParameters(msg) => write!(f, "Invalid parameters: {}", msg),
38            KeyDerivationError::DerivationFailed(msg) => write!(f, "Derivation failed: {}", msg),
39        }
40    }
41}
42
43impl std::error::Error for KeyDerivationError {}
44
45#[derive(Debug)]
46pub enum CryptError {
47    EncryptionError(String),
48    DecryptionError(String),
49}
50
51impl Display for CryptError {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        match self {
54            CryptError::EncryptionError(msg) => write!(f, "Encryption error: {}", msg),
55            CryptError::DecryptionError(msg) => write!(f, "Decryption error: {}", msg),
56        }
57    }
58}
59
60impl Error for CryptError {}
61
62/// Errors from whole-file seal/decrypt operations, which span header
63/// construction/parsing and AEAD encryption/decryption.
64#[derive(Debug)]
65pub enum FileError {
66    Header(HeaderError),
67    Crypt(CryptError),
68    /// The decrypted filename is not valid UTF-8.
69    InvalidFilename,
70    /// The decrypted metadata envelope is malformed.
71    InvalidMetadata,
72}
73
74impl From<HeaderError> for FileError {
75    fn from(e: HeaderError) -> Self {
76        FileError::Header(e)
77    }
78}
79
80impl From<CryptError> for FileError {
81    fn from(e: CryptError) -> Self {
82        FileError::Crypt(e)
83    }
84}
85
86impl Display for FileError {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        match self {
89            FileError::Header(e) => write!(f, "{}", e),
90            FileError::Crypt(e) => write!(f, "{}", e),
91            FileError::InvalidFilename => write!(f, "Decrypted filename is not valid UTF-8"),
92            FileError::InvalidMetadata => write!(f, "Decrypted metadata envelope is malformed"),
93        }
94    }
95}
96
97impl Error for FileError {}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102    use std::error::Error;
103
104    #[test]
105    fn test_header_error_display() {
106        let insufficient = HeaderError::InsufficientBytes;
107        assert_eq!(
108            format!("{}", insufficient),
109            "Insufficient bytes to read header"
110        );
111
112        let invalid = HeaderError::InvalidData;
113        assert_eq!(format!("{}", invalid), "Invalid header data");
114    }
115
116    #[test]
117    fn test_header_error_is_error_trait() {
118        let error = HeaderError::InsufficientBytes;
119        // Just ensure it implements Error trait (compilation test)
120        let _error_trait: &dyn Error = &error;
121    }
122
123    #[test]
124    fn test_key_derivation_error_display() {
125        let invalid = KeyDerivationError::InvalidParameters("test msg".to_string());
126        assert_eq!(format!("{}", invalid), "Invalid parameters: test msg");
127
128        let failed = KeyDerivationError::DerivationFailed("test msg".to_string());
129        assert_eq!(format!("{}", failed), "Derivation failed: test msg");
130    }
131
132    #[test]
133    fn test_key_derivation_error_is_error_trait() {
134        let error = KeyDerivationError::InvalidParameters("test".to_string());
135        let _error_trait: &dyn Error = &error;
136    }
137
138    #[test]
139    fn test_crypt_error_display() {
140        let encrypt = CryptError::EncryptionError("test msg".to_string());
141        assert_eq!(format!("{}", encrypt), "Encryption error: test msg");
142
143        let decrypt = CryptError::DecryptionError("test msg".to_string());
144        assert_eq!(format!("{}", decrypt), "Decryption error: test msg");
145    }
146
147    #[test]
148    fn test_crypt_error_is_error_trait() {
149        let error = CryptError::EncryptionError("test".to_string());
150        let _error_trait: &dyn Error = &error;
151    }
152}