Skip to main content

dcrypt_pke/
error.rs

1//! Error handling for PKE operations.
2use core::fmt;
3use dcrypt_algorithms::error::Error as PrimitiveError;
4use dcrypt_api::error::Error as CoreError;
5
6/// Error type for PKE operations.
7#[derive(Debug)]
8pub enum Error {
9    Primitive(PrimitiveError),
10    Api(CoreError),
11    InvalidCiphertextFormat(&'static str),
12    EncryptionFailed(&'static str),
13    DecryptionFailed(&'static str),
14    KeyDerivationFailed(&'static str),
15    UnsupportedOperation(&'static str),
16    SerializationError(&'static str),
17}
18
19impl fmt::Display for Error {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        match self {
22            Error::Primitive(e) => write!(f, "PKE primitive error: {}", e),
23            Error::Api(e) => write!(f, "PKE API error: {}", e),
24            Error::InvalidCiphertextFormat(reason) => {
25                write!(f, "Invalid PKE ciphertext format: {}", reason)
26            }
27            Error::EncryptionFailed(reason) => write!(f, "PKE encryption failed: {}", reason),
28            Error::DecryptionFailed(reason) => write!(f, "PKE decryption failed: {}", reason),
29            Error::KeyDerivationFailed(reason) => {
30                write!(f, "PKE key derivation failed: {}", reason)
31            }
32            Error::UnsupportedOperation(op) => write!(f, "PKE unsupported operation: {}", op),
33            Error::SerializationError(reason) => {
34                write!(f, "PKE internal serialization error: {}", reason)
35            }
36        }
37    }
38}
39
40#[cfg(feature = "std")]
41impl std::error::Error for Error {
42    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
43        match self {
44            Error::Primitive(e) => Some(e),
45            Error::Api(e) => Some(e),
46            _ => None,
47        }
48    }
49}
50
51impl From<PrimitiveError> for Error {
52    fn from(err: PrimitiveError) -> Self {
53        Error::Primitive(err)
54    }
55}
56
57impl From<CoreError> for Error {
58    fn from(err: CoreError) -> Self {
59        Error::Api(err)
60    }
61}
62
63// Conversion from PKE Error to API Error
64impl From<Error> for CoreError {
65    fn from(err: Error) -> Self {
66        match err {
67            Error::Primitive(e) => e.into(),
68            Error::Api(e) => e,
69            Error::InvalidCiphertextFormat(reason) => {
70                #[cfg(not(feature = "std"))]
71                let _ = reason;
72                CoreError::InvalidCiphertext {
73                    context: "ECIES",
74                    #[cfg(feature = "std")]
75                    message: reason.to_string(),
76                }
77            }
78            Error::EncryptionFailed(reason) => {
79                #[cfg(not(feature = "std"))]
80                let _ = reason;
81                CoreError::Other {
82                    context: "ECIES Encryption",
83                    #[cfg(feature = "std")]
84                    message: reason.to_string(),
85                }
86            }
87            Error::DecryptionFailed(reason) => {
88                // Provide more specific context for the AEAD-auth failure that
89                // the unit-tests look for, while keeping the generic string for
90                // every other reason.
91                let ctx: &'static str = if reason == "AEAD authentication failed" {
92                    "ECIES Decryption: AEAD authentication failed"
93                } else {
94                    "ECIES Decryption"
95                };
96                CoreError::DecryptionFailed {
97                    context: ctx,
98                    #[cfg(feature = "std")]
99                    message: reason.to_string(),
100                }
101            }
102            Error::KeyDerivationFailed(reason) => {
103                #[cfg(not(feature = "std"))]
104                let _ = reason;
105                CoreError::Other {
106                    context: "ECIES KDF",
107                    #[cfg(feature = "std")]
108                    message: reason.to_string(),
109                }
110            }
111            Error::UnsupportedOperation(op) => CoreError::NotImplemented { feature: op },
112            Error::SerializationError(reason) => {
113                #[cfg(not(feature = "std"))]
114                let _ = reason;
115                CoreError::SerializationError {
116                    context: "ECIES Internal",
117                    #[cfg(feature = "std")]
118                    message: reason.to_string(),
119                }
120            }
121        }
122    }
123}
124
125/// Result type for PKE operations.
126pub type Result<T> = core::result::Result<T, Error>;